signalpilot-ai-internal 0.3.2__py3-none-any.whl → 0.3.3__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.
Potentially problematic release.
This version of signalpilot-ai-internal might be problematic. Click here for more details.
- signalpilot_ai_internal/_version.py +1 -1
- signalpilot_ai_internal/cache_handlers.py +383 -0
- signalpilot_ai_internal/cache_service.py +552 -0
- signalpilot_ai_internal/handlers.py +35 -915
- signalpilot_ai_internal/snowflake_schema_service.py +639 -0
- signalpilot_ai_internal/unified_database_schema_service.py +742 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/package.json +3 -2
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/schemas/signalpilot-ai-internal/package.json.orig +2 -1
- signalpilot_ai_internal-0.3.3.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/384.fa432bdb7fb6b1c95ad6.js +1 -0
- signalpilot_ai_internal-0.3.3.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/447.0fea0d444fc7ba458d5a.js +1 -0
- signalpilot_ai_internal-0.3.3.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/839.c61f5bc4d0da4a0781d6.js +1 -0
- signalpilot_ai_internal-0.3.3.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/remoteEntry.2e2c6ae0baa591126b0a.js +1 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/third-party-licenses.json +6 -0
- {signalpilot_ai_internal-0.3.2.dist-info → signalpilot_ai_internal-0.3.3.dist-info}/METADATA +1 -1
- signalpilot_ai_internal-0.3.3.dist-info/RECORD +45 -0
- signalpilot_ai_internal-0.3.2.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/447.8d3d5d0480ba7396f2f5.js +0 -1
- signalpilot_ai_internal-0.3.2.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/839.5a362da0c4b891e005b3.js +0 -1
- signalpilot_ai_internal-0.3.2.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/remoteEntry.57019ad0ad044a0f8ad8.js +0 -1
- signalpilot_ai_internal-0.3.2.dist-info/RECORD +0 -40
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/etc/jupyter/jupyter_server_config.d/signalpilot_ai.json +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/install.json +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/schemas/signalpilot-ai-internal/plugin.json +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/104.04e170724f369fcbaf19.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/104.04e170724f369fcbaf19.js.LICENSE.txt +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/122.e2dadf63dc64d7b5f1ee.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/220.328403b5545f268b95c6.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/262.726e1da31a50868cb297.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/280.35d8c8b68815702a5238.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/280.35d8c8b68815702a5238.js.LICENSE.txt +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/353.72484b768a04f89bd3dd.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/364.dbec4c2dc12e7b050dcc.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/439.37e271d7a80336daabe2.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/476.9b4f05a99f5003f82094.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/481.73c7a9290b7d35a8b9c1.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/512.b58fc0093d080b8ee61c.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/553.b4042a795c91d9ff71ef.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/553.b4042a795c91d9ff71ef.js.LICENSE.txt +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/606.90aaaae46b73dc3c08fb.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/635.9720593ee20b768da3ca.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/713.8e6edc9a965bdd578ca7.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/742.91e7b516c8699eea3373.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/785.3aa564fc148b37d1d719.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/888.34054db17bcf6e87ec95.js +0 -0
- {signalpilot_ai_internal-0.3.2.data → signalpilot_ai_internal-0.3.3.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/style.js +0 -0
- {signalpilot_ai_internal-0.3.2.dist-info → signalpilot_ai_internal-0.3.3.dist-info}/WHEEL +0 -0
- {signalpilot_ai_internal-0.3.2.dist-info → signalpilot_ai_internal-0.3.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cache endpoint handlers for SignalPilot AI.
|
|
3
|
+
Provides REST API handlers for chat histories and app values caching.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
from typing import Any, Dict, Optional
|
|
8
|
+
|
|
9
|
+
from jupyter_server.base.handlers import APIHandler
|
|
10
|
+
import tornado
|
|
11
|
+
|
|
12
|
+
from .cache_service import get_cache_service
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ChatHistoriesHandler(APIHandler):
|
|
16
|
+
"""Handler for chat histories cache operations"""
|
|
17
|
+
|
|
18
|
+
@tornado.web.authenticated
|
|
19
|
+
def get(self, chat_id=None):
|
|
20
|
+
"""Get chat histories or specific chat history"""
|
|
21
|
+
try:
|
|
22
|
+
cache_service = get_cache_service()
|
|
23
|
+
|
|
24
|
+
if not cache_service.is_available():
|
|
25
|
+
self.set_status(503)
|
|
26
|
+
self.finish(json.dumps({
|
|
27
|
+
"error": "Cache service not available",
|
|
28
|
+
"message": "Persistent storage is not accessible"
|
|
29
|
+
}))
|
|
30
|
+
return
|
|
31
|
+
|
|
32
|
+
if chat_id:
|
|
33
|
+
# Get specific chat history
|
|
34
|
+
history = cache_service.get_chat_history(chat_id)
|
|
35
|
+
if history is None:
|
|
36
|
+
self.set_status(404)
|
|
37
|
+
self.finish(json.dumps({
|
|
38
|
+
"error": "Chat history not found",
|
|
39
|
+
"chat_id": chat_id
|
|
40
|
+
}))
|
|
41
|
+
else:
|
|
42
|
+
self.finish(json.dumps({
|
|
43
|
+
"chat_id": chat_id,
|
|
44
|
+
"history": history
|
|
45
|
+
}))
|
|
46
|
+
else:
|
|
47
|
+
# Get all chat histories
|
|
48
|
+
histories = cache_service.get_chat_histories()
|
|
49
|
+
self.finish(json.dumps({
|
|
50
|
+
"chat_histories": histories,
|
|
51
|
+
"count": len(histories)
|
|
52
|
+
}))
|
|
53
|
+
|
|
54
|
+
except Exception as e:
|
|
55
|
+
self.set_status(500)
|
|
56
|
+
self.finish(json.dumps({
|
|
57
|
+
"error": "Internal server error",
|
|
58
|
+
"message": str(e)
|
|
59
|
+
}))
|
|
60
|
+
|
|
61
|
+
@tornado.web.authenticated
|
|
62
|
+
def post(self, chat_id=None):
|
|
63
|
+
"""Create or update chat history"""
|
|
64
|
+
try:
|
|
65
|
+
cache_service = get_cache_service()
|
|
66
|
+
|
|
67
|
+
if not cache_service.is_available():
|
|
68
|
+
self.set_status(503)
|
|
69
|
+
self.finish(json.dumps({
|
|
70
|
+
"error": "Cache service not available",
|
|
71
|
+
"message": "Persistent storage is not accessible"
|
|
72
|
+
}))
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
# Parse request body
|
|
76
|
+
try:
|
|
77
|
+
body = json.loads(self.request.body.decode('utf-8'))
|
|
78
|
+
except json.JSONDecodeError:
|
|
79
|
+
self.set_status(400)
|
|
80
|
+
self.finish(json.dumps({
|
|
81
|
+
"error": "Invalid JSON in request body"
|
|
82
|
+
}))
|
|
83
|
+
return
|
|
84
|
+
|
|
85
|
+
if chat_id:
|
|
86
|
+
# Update specific chat history
|
|
87
|
+
history_data = body.get('history')
|
|
88
|
+
if history_data is None:
|
|
89
|
+
self.set_status(400)
|
|
90
|
+
self.finish(json.dumps({
|
|
91
|
+
"error": "Missing 'history' field in request body"
|
|
92
|
+
}))
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
success = cache_service.set_chat_history(chat_id, history_data)
|
|
96
|
+
if success:
|
|
97
|
+
self.finish(json.dumps({
|
|
98
|
+
"success": True,
|
|
99
|
+
"chat_id": chat_id,
|
|
100
|
+
"message": "Chat history updated successfully"
|
|
101
|
+
}))
|
|
102
|
+
else:
|
|
103
|
+
self.set_status(500)
|
|
104
|
+
self.finish(json.dumps({
|
|
105
|
+
"error": "Failed to save chat history"
|
|
106
|
+
}))
|
|
107
|
+
else:
|
|
108
|
+
# Bulk update operation
|
|
109
|
+
chat_histories = body.get('chat_histories', {})
|
|
110
|
+
if not isinstance(chat_histories, dict):
|
|
111
|
+
self.set_status(400)
|
|
112
|
+
self.finish(json.dumps({
|
|
113
|
+
"error": "'chat_histories' must be an object"
|
|
114
|
+
}))
|
|
115
|
+
return
|
|
116
|
+
|
|
117
|
+
# Update each chat history
|
|
118
|
+
failures = []
|
|
119
|
+
successes = []
|
|
120
|
+
|
|
121
|
+
for cid, history in chat_histories.items():
|
|
122
|
+
if cache_service.set_chat_history(cid, history):
|
|
123
|
+
successes.append(cid)
|
|
124
|
+
else:
|
|
125
|
+
failures.append(cid)
|
|
126
|
+
|
|
127
|
+
self.finish(json.dumps({
|
|
128
|
+
"success": len(failures) == 0,
|
|
129
|
+
"updated": successes,
|
|
130
|
+
"failed": failures,
|
|
131
|
+
"message": f"Updated {len(successes)} chat histories, {len(failures)} failed"
|
|
132
|
+
}))
|
|
133
|
+
|
|
134
|
+
except Exception as e:
|
|
135
|
+
self.set_status(500)
|
|
136
|
+
self.finish(json.dumps({
|
|
137
|
+
"error": "Internal server error",
|
|
138
|
+
"message": str(e)
|
|
139
|
+
}))
|
|
140
|
+
|
|
141
|
+
@tornado.web.authenticated
|
|
142
|
+
def delete(self, chat_id=None):
|
|
143
|
+
"""Delete chat history or all chat histories"""
|
|
144
|
+
try:
|
|
145
|
+
cache_service = get_cache_service()
|
|
146
|
+
|
|
147
|
+
if not cache_service.is_available():
|
|
148
|
+
self.set_status(503)
|
|
149
|
+
self.finish(json.dumps({
|
|
150
|
+
"error": "Cache service not available",
|
|
151
|
+
"message": "Persistent storage is not accessible"
|
|
152
|
+
}))
|
|
153
|
+
return
|
|
154
|
+
|
|
155
|
+
if chat_id:
|
|
156
|
+
# Delete specific chat history
|
|
157
|
+
success = cache_service.delete_chat_history(chat_id)
|
|
158
|
+
if success:
|
|
159
|
+
self.finish(json.dumps({
|
|
160
|
+
"success": True,
|
|
161
|
+
"chat_id": chat_id,
|
|
162
|
+
"message": "Chat history deleted successfully"
|
|
163
|
+
}))
|
|
164
|
+
else:
|
|
165
|
+
self.set_status(500)
|
|
166
|
+
self.finish(json.dumps({
|
|
167
|
+
"error": "Failed to delete chat history"
|
|
168
|
+
}))
|
|
169
|
+
else:
|
|
170
|
+
# Clear all chat histories
|
|
171
|
+
success = cache_service.clear_chat_histories()
|
|
172
|
+
if success:
|
|
173
|
+
self.finish(json.dumps({
|
|
174
|
+
"success": True,
|
|
175
|
+
"message": "All chat histories cleared successfully"
|
|
176
|
+
}))
|
|
177
|
+
else:
|
|
178
|
+
self.set_status(500)
|
|
179
|
+
self.finish(json.dumps({
|
|
180
|
+
"error": "Failed to clear chat histories"
|
|
181
|
+
}))
|
|
182
|
+
|
|
183
|
+
except Exception as e:
|
|
184
|
+
self.set_status(500)
|
|
185
|
+
self.finish(json.dumps({
|
|
186
|
+
"error": "Internal server error",
|
|
187
|
+
"message": str(e)
|
|
188
|
+
}))
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class AppValuesHandler(APIHandler):
|
|
192
|
+
"""Handler for app values cache operations"""
|
|
193
|
+
|
|
194
|
+
@tornado.web.authenticated
|
|
195
|
+
def get(self, key=None):
|
|
196
|
+
"""Get app values or specific app value"""
|
|
197
|
+
try:
|
|
198
|
+
cache_service = get_cache_service()
|
|
199
|
+
|
|
200
|
+
if not cache_service.is_available():
|
|
201
|
+
self.set_status(503)
|
|
202
|
+
self.finish(json.dumps({
|
|
203
|
+
"error": "Cache service not available",
|
|
204
|
+
"message": "Persistent storage is not accessible"
|
|
205
|
+
}))
|
|
206
|
+
return
|
|
207
|
+
|
|
208
|
+
if key:
|
|
209
|
+
# Get specific app value
|
|
210
|
+
default = self.get_argument('default', None)
|
|
211
|
+
try:
|
|
212
|
+
if default:
|
|
213
|
+
default = json.loads(default)
|
|
214
|
+
except json.JSONDecodeError:
|
|
215
|
+
pass # Use string default
|
|
216
|
+
|
|
217
|
+
value = cache_service.get_app_value(key, default)
|
|
218
|
+
self.finish(json.dumps({
|
|
219
|
+
"key": key,
|
|
220
|
+
"value": value
|
|
221
|
+
}))
|
|
222
|
+
else:
|
|
223
|
+
# Get all app values
|
|
224
|
+
values = cache_service.get_app_values()
|
|
225
|
+
self.finish(json.dumps({
|
|
226
|
+
"app_values": values,
|
|
227
|
+
"count": len(values)
|
|
228
|
+
}))
|
|
229
|
+
|
|
230
|
+
except Exception as e:
|
|
231
|
+
self.set_status(500)
|
|
232
|
+
self.finish(json.dumps({
|
|
233
|
+
"error": "Internal server error",
|
|
234
|
+
"message": str(e)
|
|
235
|
+
}))
|
|
236
|
+
|
|
237
|
+
@tornado.web.authenticated
|
|
238
|
+
def post(self, key=None):
|
|
239
|
+
"""Create or update app value"""
|
|
240
|
+
try:
|
|
241
|
+
cache_service = get_cache_service()
|
|
242
|
+
|
|
243
|
+
if not cache_service.is_available():
|
|
244
|
+
self.set_status(503)
|
|
245
|
+
self.finish(json.dumps({
|
|
246
|
+
"error": "Cache service not available",
|
|
247
|
+
"message": "Persistent storage is not accessible"
|
|
248
|
+
}))
|
|
249
|
+
return
|
|
250
|
+
|
|
251
|
+
# Parse request body
|
|
252
|
+
try:
|
|
253
|
+
body = json.loads(self.request.body.decode('utf-8'))
|
|
254
|
+
except json.JSONDecodeError:
|
|
255
|
+
self.set_status(400)
|
|
256
|
+
self.finish(json.dumps({
|
|
257
|
+
"error": "Invalid JSON in request body"
|
|
258
|
+
}))
|
|
259
|
+
return
|
|
260
|
+
|
|
261
|
+
if key:
|
|
262
|
+
# Update specific app value
|
|
263
|
+
value_data = body.get('value')
|
|
264
|
+
if value_data is None:
|
|
265
|
+
self.set_status(400)
|
|
266
|
+
self.finish(json.dumps({
|
|
267
|
+
"error": "Missing 'value' field in request body"
|
|
268
|
+
}))
|
|
269
|
+
return
|
|
270
|
+
|
|
271
|
+
success = cache_service.set_app_value(key, value_data)
|
|
272
|
+
if success:
|
|
273
|
+
self.finish(json.dumps({
|
|
274
|
+
"success": True,
|
|
275
|
+
"key": key,
|
|
276
|
+
"message": "App value updated successfully"
|
|
277
|
+
}))
|
|
278
|
+
else:
|
|
279
|
+
self.set_status(500)
|
|
280
|
+
self.finish(json.dumps({
|
|
281
|
+
"error": "Failed to save app value"
|
|
282
|
+
}))
|
|
283
|
+
else:
|
|
284
|
+
# Bulk update operation
|
|
285
|
+
app_values = body.get('app_values', {})
|
|
286
|
+
if not isinstance(app_values, dict):
|
|
287
|
+
self.set_status(400)
|
|
288
|
+
self.finish(json.dumps({
|
|
289
|
+
"error": "'app_values' must be an object"
|
|
290
|
+
}))
|
|
291
|
+
return
|
|
292
|
+
|
|
293
|
+
# Update each app value
|
|
294
|
+
failures = []
|
|
295
|
+
successes = []
|
|
296
|
+
|
|
297
|
+
for k, value in app_values.items():
|
|
298
|
+
if cache_service.set_app_value(k, value):
|
|
299
|
+
successes.append(k)
|
|
300
|
+
else:
|
|
301
|
+
failures.append(k)
|
|
302
|
+
|
|
303
|
+
self.finish(json.dumps({
|
|
304
|
+
"success": len(failures) == 0,
|
|
305
|
+
"updated": successes,
|
|
306
|
+
"failed": failures,
|
|
307
|
+
"message": f"Updated {len(successes)} app values, {len(failures)} failed"
|
|
308
|
+
}))
|
|
309
|
+
|
|
310
|
+
except Exception as e:
|
|
311
|
+
self.set_status(500)
|
|
312
|
+
self.finish(json.dumps({
|
|
313
|
+
"error": "Internal server error",
|
|
314
|
+
"message": str(e)
|
|
315
|
+
}))
|
|
316
|
+
|
|
317
|
+
@tornado.web.authenticated
|
|
318
|
+
def delete(self, key=None):
|
|
319
|
+
"""Delete app value or all app values"""
|
|
320
|
+
try:
|
|
321
|
+
cache_service = get_cache_service()
|
|
322
|
+
|
|
323
|
+
if not cache_service.is_available():
|
|
324
|
+
self.set_status(503)
|
|
325
|
+
self.finish(json.dumps({
|
|
326
|
+
"error": "Cache service not available",
|
|
327
|
+
"message": "Persistent storage is not accessible"
|
|
328
|
+
}))
|
|
329
|
+
return
|
|
330
|
+
|
|
331
|
+
if key:
|
|
332
|
+
# Delete specific app value
|
|
333
|
+
success = cache_service.delete_app_value(key)
|
|
334
|
+
if success:
|
|
335
|
+
self.finish(json.dumps({
|
|
336
|
+
"success": True,
|
|
337
|
+
"key": key,
|
|
338
|
+
"message": "App value deleted successfully"
|
|
339
|
+
}))
|
|
340
|
+
else:
|
|
341
|
+
self.set_status(500)
|
|
342
|
+
self.finish(json.dumps({
|
|
343
|
+
"error": "Failed to delete app value"
|
|
344
|
+
}))
|
|
345
|
+
else:
|
|
346
|
+
# Clear all app values
|
|
347
|
+
success = cache_service.clear_app_values()
|
|
348
|
+
if success:
|
|
349
|
+
self.finish(json.dumps({
|
|
350
|
+
"success": True,
|
|
351
|
+
"message": "All app values cleared successfully"
|
|
352
|
+
}))
|
|
353
|
+
else:
|
|
354
|
+
self.set_status(500)
|
|
355
|
+
self.finish(json.dumps({
|
|
356
|
+
"error": "Failed to clear app values"
|
|
357
|
+
}))
|
|
358
|
+
|
|
359
|
+
except Exception as e:
|
|
360
|
+
self.set_status(500)
|
|
361
|
+
self.finish(json.dumps({
|
|
362
|
+
"error": "Internal server error",
|
|
363
|
+
"message": str(e)
|
|
364
|
+
}))
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
class CacheInfoHandler(APIHandler):
|
|
368
|
+
"""Handler for cache service information"""
|
|
369
|
+
|
|
370
|
+
@tornado.web.authenticated
|
|
371
|
+
def get(self):
|
|
372
|
+
"""Get cache service information and statistics"""
|
|
373
|
+
try:
|
|
374
|
+
cache_service = get_cache_service()
|
|
375
|
+
info = cache_service.get_cache_info()
|
|
376
|
+
self.finish(json.dumps(info))
|
|
377
|
+
|
|
378
|
+
except Exception as e:
|
|
379
|
+
self.set_status(500)
|
|
380
|
+
self.finish(json.dumps({
|
|
381
|
+
"error": "Internal server error",
|
|
382
|
+
"message": str(e)
|
|
383
|
+
}))
|