llms-py 3.0.0__py3-none-any.whl → 3.0.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- llms/index.html +77 -35
- llms/llms.json +23 -72
- llms/main.py +732 -1786
- llms/providers.json +1 -1
- llms/{extensions/analytics/ui/index.mjs → ui/Analytics.mjs} +238 -154
- llms/ui/App.mjs +60 -151
- llms/ui/Avatar.mjs +85 -0
- llms/ui/Brand.mjs +52 -0
- llms/ui/ChatPrompt.mjs +606 -0
- llms/ui/Main.mjs +873 -0
- llms/ui/ModelSelector.mjs +693 -0
- llms/ui/OAuthSignIn.mjs +92 -0
- llms/ui/ProviderIcon.mjs +36 -0
- llms/ui/ProviderStatus.mjs +105 -0
- llms/{extensions/app/ui → ui}/Recents.mjs +65 -91
- llms/ui/{modules/chat/SettingsDialog.mjs → SettingsDialog.mjs} +9 -9
- llms/{extensions/app/ui/index.mjs → ui/Sidebar.mjs} +58 -124
- llms/ui/SignIn.mjs +64 -0
- llms/ui/SystemPromptEditor.mjs +31 -0
- llms/ui/SystemPromptSelector.mjs +56 -0
- llms/ui/Welcome.mjs +8 -0
- llms/ui/ai.mjs +53 -125
- llms/ui/app.css +111 -1837
- llms/ui/lib/charts.mjs +13 -9
- llms/ui/lib/servicestack-vue.mjs +3 -3
- llms/ui/lib/vue.min.mjs +9 -10
- llms/ui/lib/vue.mjs +1602 -1763
- llms/ui/markdown.mjs +2 -10
- llms/ui/tailwind.input.css +80 -496
- llms/ui/threadStore.mjs +572 -0
- llms/ui/utils.mjs +117 -113
- llms/ui.json +1069 -0
- {llms_py-3.0.0.dist-info → llms_py-3.0.0b1.dist-info}/METADATA +1 -1
- llms_py-3.0.0b1.dist-info/RECORD +49 -0
- llms/__pycache__/__init__.cpython-312.pyc +0 -0
- llms/__pycache__/__init__.cpython-313.pyc +0 -0
- llms/__pycache__/__init__.cpython-314.pyc +0 -0
- llms/__pycache__/__main__.cpython-312.pyc +0 -0
- llms/__pycache__/__main__.cpython-314.pyc +0 -0
- llms/__pycache__/llms.cpython-312.pyc +0 -0
- llms/__pycache__/main.cpython-312.pyc +0 -0
- llms/__pycache__/main.cpython-313.pyc +0 -0
- llms/__pycache__/main.cpython-314.pyc +0 -0
- llms/__pycache__/plugins.cpython-314.pyc +0 -0
- llms/extensions/app/README.md +0 -20
- llms/extensions/app/__init__.py +0 -530
- llms/extensions/app/__pycache__/__init__.cpython-314.pyc +0 -0
- llms/extensions/app/__pycache__/db.cpython-314.pyc +0 -0
- llms/extensions/app/__pycache__/db_manager.cpython-314.pyc +0 -0
- llms/extensions/app/db.py +0 -644
- llms/extensions/app/db_manager.py +0 -195
- llms/extensions/app/requests.json +0 -9073
- llms/extensions/app/threads.json +0 -15290
- llms/extensions/app/ui/threadStore.mjs +0 -411
- llms/extensions/core_tools/CALCULATOR.md +0 -32
- llms/extensions/core_tools/__init__.py +0 -598
- llms/extensions/core_tools/__pycache__/__init__.cpython-314.pyc +0 -0
- llms/extensions/core_tools/ui/codemirror/addon/edit/closebrackets.js +0 -201
- llms/extensions/core_tools/ui/codemirror/addon/edit/closetag.js +0 -185
- llms/extensions/core_tools/ui/codemirror/addon/edit/continuelist.js +0 -101
- llms/extensions/core_tools/ui/codemirror/addon/edit/matchbrackets.js +0 -160
- llms/extensions/core_tools/ui/codemirror/addon/edit/matchtags.js +0 -66
- llms/extensions/core_tools/ui/codemirror/addon/edit/trailingspace.js +0 -27
- llms/extensions/core_tools/ui/codemirror/addon/selection/active-line.js +0 -72
- llms/extensions/core_tools/ui/codemirror/addon/selection/mark-selection.js +0 -119
- llms/extensions/core_tools/ui/codemirror/addon/selection/selection-pointer.js +0 -98
- llms/extensions/core_tools/ui/codemirror/doc/docs.css +0 -225
- llms/extensions/core_tools/ui/codemirror/doc/source_sans.woff +0 -0
- llms/extensions/core_tools/ui/codemirror/lib/codemirror.css +0 -344
- llms/extensions/core_tools/ui/codemirror/lib/codemirror.js +0 -9884
- llms/extensions/core_tools/ui/codemirror/mode/clike/clike.js +0 -942
- llms/extensions/core_tools/ui/codemirror/mode/javascript/index.html +0 -118
- llms/extensions/core_tools/ui/codemirror/mode/javascript/javascript.js +0 -962
- llms/extensions/core_tools/ui/codemirror/mode/javascript/typescript.html +0 -62
- llms/extensions/core_tools/ui/codemirror/mode/python/python.js +0 -402
- llms/extensions/core_tools/ui/codemirror/theme/dracula.css +0 -40
- llms/extensions/core_tools/ui/codemirror/theme/mocha.css +0 -135
- llms/extensions/core_tools/ui/index.mjs +0 -650
- llms/extensions/gallery/README.md +0 -61
- llms/extensions/gallery/__init__.py +0 -61
- llms/extensions/gallery/__pycache__/__init__.cpython-314.pyc +0 -0
- llms/extensions/gallery/__pycache__/db.cpython-314.pyc +0 -0
- llms/extensions/gallery/db.py +0 -298
- llms/extensions/gallery/ui/index.mjs +0 -482
- llms/extensions/katex/README.md +0 -39
- llms/extensions/katex/__init__.py +0 -6
- llms/extensions/katex/__pycache__/__init__.cpython-314.pyc +0 -0
- llms/extensions/katex/ui/README.md +0 -125
- llms/extensions/katex/ui/contrib/auto-render.js +0 -338
- llms/extensions/katex/ui/contrib/auto-render.min.js +0 -1
- llms/extensions/katex/ui/contrib/auto-render.mjs +0 -244
- llms/extensions/katex/ui/contrib/copy-tex.js +0 -127
- llms/extensions/katex/ui/contrib/copy-tex.min.js +0 -1
- llms/extensions/katex/ui/contrib/copy-tex.mjs +0 -105
- llms/extensions/katex/ui/contrib/mathtex-script-type.js +0 -109
- llms/extensions/katex/ui/contrib/mathtex-script-type.min.js +0 -1
- llms/extensions/katex/ui/contrib/mathtex-script-type.mjs +0 -24
- llms/extensions/katex/ui/contrib/mhchem.js +0 -3213
- llms/extensions/katex/ui/contrib/mhchem.min.js +0 -1
- llms/extensions/katex/ui/contrib/mhchem.mjs +0 -3109
- llms/extensions/katex/ui/contrib/render-a11y-string.js +0 -887
- llms/extensions/katex/ui/contrib/render-a11y-string.min.js +0 -1
- llms/extensions/katex/ui/contrib/render-a11y-string.mjs +0 -800
- llms/extensions/katex/ui/fonts/KaTeX_AMS-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_AMS-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-Bold.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-Bold.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-Bold.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-Italic.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-Italic.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-Italic.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Main-Regular.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Math-Italic.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Math-Italic.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Math-Italic.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Script-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Script-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Script-Regular.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size1-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size1-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size2-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size2-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size3-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size3-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size4-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size4-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- llms/extensions/katex/ui/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- llms/extensions/katex/ui/index.mjs +0 -92
- llms/extensions/katex/ui/katex-swap.css +0 -1230
- llms/extensions/katex/ui/katex-swap.min.css +0 -1
- llms/extensions/katex/ui/katex.css +0 -1230
- llms/extensions/katex/ui/katex.js +0 -19080
- llms/extensions/katex/ui/katex.min.css +0 -1
- llms/extensions/katex/ui/katex.min.js +0 -1
- llms/extensions/katex/ui/katex.min.mjs +0 -1
- llms/extensions/katex/ui/katex.mjs +0 -18547
- llms/extensions/providers/__init__.py +0 -18
- llms/extensions/providers/__pycache__/__init__.cpython-314.pyc +0 -0
- llms/extensions/providers/__pycache__/anthropic.cpython-314.pyc +0 -0
- llms/extensions/providers/__pycache__/chutes.cpython-314.pyc +0 -0
- llms/extensions/providers/__pycache__/google.cpython-314.pyc +0 -0
- llms/extensions/providers/__pycache__/nvidia.cpython-314.pyc +0 -0
- llms/extensions/providers/__pycache__/openai.cpython-314.pyc +0 -0
- llms/extensions/providers/__pycache__/openrouter.cpython-314.pyc +0 -0
- llms/extensions/providers/anthropic.py +0 -229
- llms/extensions/providers/chutes.py +0 -155
- llms/extensions/providers/google.py +0 -378
- llms/extensions/providers/nvidia.py +0 -105
- llms/extensions/providers/openai.py +0 -156
- llms/extensions/providers/openrouter.py +0 -72
- llms/extensions/system_prompts/README.md +0 -22
- llms/extensions/system_prompts/__init__.py +0 -45
- llms/extensions/system_prompts/__pycache__/__init__.cpython-314.pyc +0 -0
- llms/extensions/system_prompts/ui/index.mjs +0 -280
- llms/extensions/system_prompts/ui/prompts.json +0 -1067
- llms/extensions/tools/__init__.py +0 -5
- llms/extensions/tools/__pycache__/__init__.cpython-314.pyc +0 -0
- llms/extensions/tools/ui/index.mjs +0 -204
- llms/providers-extra.json +0 -356
- llms/ui/ctx.mjs +0 -365
- llms/ui/index.mjs +0 -129
- llms/ui/modules/chat/ChatBody.mjs +0 -691
- llms/ui/modules/chat/index.mjs +0 -828
- llms/ui/modules/layout.mjs +0 -243
- llms/ui/modules/model-selector.mjs +0 -851
- llms_py-3.0.0.dist-info/RECORD +0 -202
- {llms_py-3.0.0.dist-info → llms_py-3.0.0b1.dist-info}/WHEEL +0 -0
- {llms_py-3.0.0.dist-info → llms_py-3.0.0b1.dist-info}/entry_points.txt +0 -0
- {llms_py-3.0.0.dist-info → llms_py-3.0.0b1.dist-info}/licenses/LICENSE +0 -0
- {llms_py-3.0.0.dist-info → llms_py-3.0.0b1.dist-info}/top_level.txt +0 -0
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import sqlite3
|
|
3
|
-
from queue import Empty, Queue
|
|
4
|
-
from threading import Event, Thread
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def create_reader_connection(db_path):
|
|
8
|
-
conn = sqlite3.connect(db_path, timeout=1.0) # Lower - reads should be fast
|
|
9
|
-
conn.execute("PRAGMA query_only=1") # Read-only optimization
|
|
10
|
-
return conn
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def create_writer_connection(db_path):
|
|
14
|
-
conn = sqlite3.connect(db_path)
|
|
15
|
-
conn.execute("PRAGMA busy_timeout=5000") # Reasonable timeout for busy connections
|
|
16
|
-
conn.execute("PRAGMA journal_mode=WAL") # Enable WAL mode for better concurrency
|
|
17
|
-
conn.execute("PRAGMA cache_size=-128000") # Increase cache size for better performance
|
|
18
|
-
conn.execute("PRAGMA synchronous=NORMAL") # Reasonable durability/performance balance
|
|
19
|
-
return conn
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def writer_thread(ctx, db_path, task_queue, stop_event):
|
|
23
|
-
conn = create_writer_connection(db_path)
|
|
24
|
-
try:
|
|
25
|
-
while not stop_event.is_set():
|
|
26
|
-
try:
|
|
27
|
-
# Use timeout to check stop_event periodically
|
|
28
|
-
task = task_queue.get(timeout=0.1)
|
|
29
|
-
|
|
30
|
-
if task is None: # Poison pill for clean shutdown
|
|
31
|
-
break
|
|
32
|
-
|
|
33
|
-
sql, args, callback = task # Optional callback for results
|
|
34
|
-
|
|
35
|
-
try:
|
|
36
|
-
ctx.dbg("SQL>" + ("\n" if "\n" in sql else " ") + sql)
|
|
37
|
-
cursor = conn.execute(sql, args)
|
|
38
|
-
conn.commit()
|
|
39
|
-
ctx.dbg(f"lastrowid {cursor.lastrowid}, rowcount {cursor.rowcount}")
|
|
40
|
-
if callback:
|
|
41
|
-
callback(cursor.lastrowid, cursor.rowcount)
|
|
42
|
-
except sqlite3.Error as e:
|
|
43
|
-
ctx.err("writer_thread", e)
|
|
44
|
-
if callback:
|
|
45
|
-
callback(None, None, error=e)
|
|
46
|
-
finally:
|
|
47
|
-
task_queue.task_done()
|
|
48
|
-
|
|
49
|
-
except Empty:
|
|
50
|
-
continue
|
|
51
|
-
|
|
52
|
-
finally:
|
|
53
|
-
conn.close()
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class DbManager:
|
|
57
|
-
def __init__(self, ctx, db_path):
|
|
58
|
-
if db_path is None:
|
|
59
|
-
raise ValueError("db_path is required")
|
|
60
|
-
self.ctx = ctx
|
|
61
|
-
self.db_path = db_path
|
|
62
|
-
self.task_queue = Queue()
|
|
63
|
-
self.stop_event = Event()
|
|
64
|
-
self.writer_thread = Thread(target=writer_thread, args=(ctx, db_path, self.task_queue, self.stop_event))
|
|
65
|
-
self.writer_thread.start()
|
|
66
|
-
self.read_only_pool = Queue()
|
|
67
|
-
|
|
68
|
-
def create_reader_connection(self):
|
|
69
|
-
return create_reader_connection(self.db_path)
|
|
70
|
-
|
|
71
|
-
def create_writer_connection(self):
|
|
72
|
-
return create_writer_connection(self.db_path)
|
|
73
|
-
|
|
74
|
-
def resolve_connection(self):
|
|
75
|
-
try:
|
|
76
|
-
return self.read_only_pool.get_nowait()
|
|
77
|
-
except Empty:
|
|
78
|
-
return self.create_reader_connection()
|
|
79
|
-
|
|
80
|
-
def write(self, query, args=None, callback=None):
|
|
81
|
-
"""
|
|
82
|
-
Execute a write operation asynchronously.
|
|
83
|
-
|
|
84
|
-
Args:
|
|
85
|
-
query (str): The SQL query to execute.
|
|
86
|
-
args (tuple, optional): Arguments for the query.
|
|
87
|
-
callback (callable, optional): A function called after execution with signature:
|
|
88
|
-
callback(lastrowid, rowcount, error=None)
|
|
89
|
-
- lastrowid (int): output of cursor.lastrowid
|
|
90
|
-
- rowcount (int): output of cursor.rowcount
|
|
91
|
-
- error (Exception): exception if operation failed, else None
|
|
92
|
-
"""
|
|
93
|
-
self.task_queue.put((query, args, callback))
|
|
94
|
-
|
|
95
|
-
def log_sql(self, sql, parameters=None):
|
|
96
|
-
if self.ctx.debug:
|
|
97
|
-
self.ctx.dbg("SQL>" + ("\n" if "\n" in sql else " ") + sql + ("\n" if parameters else "") + str(parameters))
|
|
98
|
-
|
|
99
|
-
def exec(self, connection, sql, parameters=None):
|
|
100
|
-
self.log_sql(sql, parameters)
|
|
101
|
-
return connection.execute(sql, parameters or ())
|
|
102
|
-
|
|
103
|
-
def all(self, sql, parameters=None, connection=None):
|
|
104
|
-
conn = self.resolve_connection() if connection is None else connection
|
|
105
|
-
|
|
106
|
-
try:
|
|
107
|
-
self.log_sql(sql, parameters)
|
|
108
|
-
conn.row_factory = sqlite3.Row
|
|
109
|
-
cursor = conn.execute(sql, parameters or ())
|
|
110
|
-
rows = [dict(row) for row in cursor.fetchall()]
|
|
111
|
-
return rows
|
|
112
|
-
finally:
|
|
113
|
-
if connection is None:
|
|
114
|
-
conn.row_factory = None
|
|
115
|
-
self.read_only_pool.put(conn)
|
|
116
|
-
|
|
117
|
-
def one(self, sql, parameters=None, connection=None):
|
|
118
|
-
conn = self.resolve_connection() if connection is None else connection
|
|
119
|
-
|
|
120
|
-
try:
|
|
121
|
-
self.log_sql(sql, parameters)
|
|
122
|
-
conn.row_factory = sqlite3.Row
|
|
123
|
-
cursor = conn.execute(sql, parameters or ())
|
|
124
|
-
row = cursor.fetchone()
|
|
125
|
-
return dict(row) if row else None
|
|
126
|
-
finally:
|
|
127
|
-
if connection is None:
|
|
128
|
-
conn.row_factory = None
|
|
129
|
-
self.read_only_pool.put(conn)
|
|
130
|
-
|
|
131
|
-
def scalar(self, sql, parameters=None, connection=None):
|
|
132
|
-
conn = self.resolve_connection() if connection is None else connection
|
|
133
|
-
|
|
134
|
-
try:
|
|
135
|
-
self.log_sql(sql, parameters)
|
|
136
|
-
conn.row_factory = sqlite3.Row
|
|
137
|
-
cursor = conn.execute(sql, parameters or ())
|
|
138
|
-
row = cursor.fetchone()
|
|
139
|
-
return row[0] if row else None
|
|
140
|
-
finally:
|
|
141
|
-
if connection is None:
|
|
142
|
-
conn.row_factory = None
|
|
143
|
-
self.read_only_pool.put(conn)
|
|
144
|
-
|
|
145
|
-
def column(self, sql, parameters=None, connection=None):
|
|
146
|
-
"""
|
|
147
|
-
Execute a 1 column query and return the values as a list.
|
|
148
|
-
"""
|
|
149
|
-
conn = self.resolve_connection() if connection is None else connection
|
|
150
|
-
|
|
151
|
-
try:
|
|
152
|
-
self.log_sql(sql, parameters)
|
|
153
|
-
cursor = conn.execute(sql, parameters or ())
|
|
154
|
-
return [row[0] for row in cursor.fetchall()]
|
|
155
|
-
finally:
|
|
156
|
-
if connection is None:
|
|
157
|
-
self.read_only_pool.put(conn)
|
|
158
|
-
|
|
159
|
-
def dict(self, sql, parameters=None, connection=None):
|
|
160
|
-
"""
|
|
161
|
-
Execute a 2 column query and return the keys as the first column and the values as the second column.
|
|
162
|
-
"""
|
|
163
|
-
conn = self.resolve_connection() if connection is None else connection
|
|
164
|
-
|
|
165
|
-
try:
|
|
166
|
-
self.log_sql(sql, parameters)
|
|
167
|
-
conn.row_factory = sqlite3.Row
|
|
168
|
-
cursor = conn.execute(sql, parameters or ())
|
|
169
|
-
rows = cursor.fetchall()
|
|
170
|
-
return {row[0]: row[1] for row in rows}
|
|
171
|
-
finally:
|
|
172
|
-
if connection is None:
|
|
173
|
-
conn.row_factory = None
|
|
174
|
-
self.read_only_pool.put(conn)
|
|
175
|
-
|
|
176
|
-
# Helper to safely dump JSON if value exists
|
|
177
|
-
def value(self, val):
|
|
178
|
-
if val is None or val == "":
|
|
179
|
-
return None
|
|
180
|
-
if isinstance(val, (dict, list)):
|
|
181
|
-
return json.dumps(val)
|
|
182
|
-
return val
|
|
183
|
-
|
|
184
|
-
def close(self):
|
|
185
|
-
self.ctx.dbg("Closing database")
|
|
186
|
-
self.stop_event.set()
|
|
187
|
-
self.task_queue.put(None) # Poison pill to signal shutdown
|
|
188
|
-
self.writer_thread.join()
|
|
189
|
-
|
|
190
|
-
while not self.read_only_pool.empty():
|
|
191
|
-
try:
|
|
192
|
-
conn = self.read_only_pool.get_nowait()
|
|
193
|
-
conn.close()
|
|
194
|
-
except Empty:
|
|
195
|
-
break
|