qalita 2.3.1__py3-none-any.whl → 2.5.2__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.
Files changed (95) hide show
  1. qalita/__main__.py +213 -9
  2. qalita/commands/{agent.py → worker.py} +89 -89
  3. qalita/internal/config.py +26 -19
  4. qalita/internal/utils.py +1 -1
  5. qalita/web/app.py +97 -14
  6. qalita/web/blueprints/context.py +13 -60
  7. qalita/web/blueprints/dashboard.py +35 -76
  8. qalita/web/blueprints/helpers.py +154 -63
  9. qalita/web/blueprints/sources.py +29 -61
  10. qalita/web/blueprints/{agents.py → workers.py} +108 -185
  11. qalita-2.5.2.dist-info/METADATA +66 -0
  12. qalita-2.5.2.dist-info/RECORD +24 -0
  13. {qalita-2.3.1.dist-info → qalita-2.5.2.dist-info}/WHEEL +1 -1
  14. qalita-2.5.2.dist-info/entry_points.txt +2 -0
  15. qalita/web/blueprints/studio.py +0 -1255
  16. qalita/web/public/chatgpt.svg +0 -3
  17. qalita/web/public/claude.png +0 -0
  18. qalita/web/public/favicon.ico +0 -0
  19. qalita/web/public/gemini.png +0 -0
  20. qalita/web/public/logo-no-slogan.png +0 -0
  21. qalita/web/public/logo-white-no-slogan.svg +0 -11
  22. qalita/web/public/mistral.svg +0 -1
  23. qalita/web/public/noise.webp +0 -0
  24. qalita/web/public/ollama.png +0 -0
  25. qalita/web/public/platform.png +0 -0
  26. qalita/web/public/sources-logos/alloy-db.png +0 -0
  27. qalita/web/public/sources-logos/amazon-athena.png +0 -0
  28. qalita/web/public/sources-logos/amazon-rds.png +0 -0
  29. qalita/web/public/sources-logos/api.svg +0 -2
  30. qalita/web/public/sources-logos/avro.svg +0 -20
  31. qalita/web/public/sources-logos/azure-database-mysql.png +0 -0
  32. qalita/web/public/sources-logos/azure-database-postgresql.png +0 -0
  33. qalita/web/public/sources-logos/azure-sql-database.png +0 -0
  34. qalita/web/public/sources-logos/azure-sql-managed-instance.png +0 -0
  35. qalita/web/public/sources-logos/azure-synapse-analytics.png +0 -0
  36. qalita/web/public/sources-logos/azure_blob.svg +0 -1
  37. qalita/web/public/sources-logos/bigquery.png +0 -0
  38. qalita/web/public/sources-logos/cassandra.svg +0 -254
  39. qalita/web/public/sources-logos/clickhouse.png +0 -0
  40. qalita/web/public/sources-logos/cloud-sql.png +0 -0
  41. qalita/web/public/sources-logos/cockroach-db.png +0 -0
  42. qalita/web/public/sources-logos/csv.svg +0 -1
  43. qalita/web/public/sources-logos/database.svg +0 -3
  44. qalita/web/public/sources-logos/databricks.png +0 -0
  45. qalita/web/public/sources-logos/duckdb.png +0 -0
  46. qalita/web/public/sources-logos/elasticsearch.svg +0 -1
  47. qalita/web/public/sources-logos/excel.svg +0 -1
  48. qalita/web/public/sources-logos/file.svg +0 -1
  49. qalita/web/public/sources-logos/folder.svg +0 -6
  50. qalita/web/public/sources-logos/gcs.png +0 -0
  51. qalita/web/public/sources-logos/hdfs.svg +0 -1
  52. qalita/web/public/sources-logos/ibm-db2.png +0 -0
  53. qalita/web/public/sources-logos/json.png +0 -0
  54. qalita/web/public/sources-logos/maria-db.png +0 -0
  55. qalita/web/public/sources-logos/mongodb.svg +0 -1
  56. qalita/web/public/sources-logos/mssql.svg +0 -1
  57. qalita/web/public/sources-logos/mysql.svg +0 -7
  58. qalita/web/public/sources-logos/oracle.svg +0 -4
  59. qalita/web/public/sources-logos/parquet.svg +0 -16
  60. qalita/web/public/sources-logos/picture.png +0 -0
  61. qalita/web/public/sources-logos/postgresql.svg +0 -22
  62. qalita/web/public/sources-logos/questdb.png +0 -0
  63. qalita/web/public/sources-logos/redshift.png +0 -0
  64. qalita/web/public/sources-logos/s3.svg +0 -34
  65. qalita/web/public/sources-logos/sap-hana.png +0 -0
  66. qalita/web/public/sources-logos/sftp.png +0 -0
  67. qalita/web/public/sources-logos/single-store.png +0 -0
  68. qalita/web/public/sources-logos/snowflake.png +0 -0
  69. qalita/web/public/sources-logos/sqlite.svg +0 -104
  70. qalita/web/public/sources-logos/sqlserver.png +0 -0
  71. qalita/web/public/sources-logos/starburst.png +0 -0
  72. qalita/web/public/sources-logos/stream.png +0 -0
  73. qalita/web/public/sources-logos/teradata.png +0 -0
  74. qalita/web/public/sources-logos/timescale.png +0 -0
  75. qalita/web/public/sources-logos/xls.svg +0 -1
  76. qalita/web/public/sources-logos/xlsx.svg +0 -1
  77. qalita/web/public/sources-logos/yugabyte-db.png +0 -0
  78. qalita/web/public/studio-logo.svg +0 -10
  79. qalita/web/public/studio.css +0 -304
  80. qalita/web/public/studio.png +0 -0
  81. qalita/web/public/styles.css +0 -682
  82. qalita/web/templates/dashboard.html +0 -373
  83. qalita/web/templates/navbar.html +0 -40
  84. qalita/web/templates/sources/added.html +0 -57
  85. qalita/web/templates/sources/edit.html +0 -411
  86. qalita/web/templates/sources/select-source.html +0 -128
  87. qalita/web/templates/studio/agent-panel.html +0 -769
  88. qalita/web/templates/studio/context-panel.html +0 -300
  89. qalita/web/templates/studio/index.html +0 -79
  90. qalita/web/templates/studio/navbar.html +0 -14
  91. qalita/web/templates/studio/view-panel.html +0 -529
  92. qalita-2.3.1.dist-info/METADATA +0 -58
  93. qalita-2.3.1.dist-info/RECORD +0 -101
  94. qalita-2.3.1.dist-info/entry_points.txt +0 -3
  95. {qalita-2.3.1.dist-info → qalita-2.5.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,529 +0,0 @@
1
- <div id="view_panel_root">
2
- <div id="view_tabs"
3
- style="display:flex; align-items:center; gap:6px; border-bottom:1px solid #e5e7eb; padding:4px 0; margin-bottom:8px; overflow:auto;">
4
- </div>
5
- <div class="muted" id="view_panel_splash"
6
- style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%;">
7
- <h1>View Panel</h1>
8
- <p>Here will be displayed contextualized data.</p>
9
- </div>
10
-
11
- <div id="vp_error" style="display:none; margin:8px 0; padding:8px 10px; border:1px solid #fecaca; background:#fef2f2; color:#b91c1c; border-radius:6px; font-size:12px;"></div>
12
-
13
- <div id="vp_image" style="display:none; height:100%; overflow:auto;">
14
- <img id="vp_image_img" alt="image" style="max-width:100%; height:auto; display:block; margin: 0 auto;" />
15
- </div>
16
-
17
- <div id="vp_pdf" style="display:none; height:100%;">
18
- <iframe id="vp_pdf_iframe" title="PDF" style="width:100%; height:100%; border:0;"></iframe>
19
- </div>
20
-
21
- <div id="vp_text" style="display:none; height:100%; overflow:auto;">
22
- <pre id="vp_text_pre"
23
- style="white-space:pre-wrap; word-break:break-word; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; font-size: 12px; line-height: 1.5; padding: 8px;"></pre>
24
- </div>
25
-
26
- <div id="vp_json" style="display:none; height:100%; overflow:auto;">
27
- <pre id="vp_json_pre"
28
- style="white-space:pre; word-break:normal; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; font-size: 12px; line-height: 1.5; padding: 8px;"></pre>
29
- </div>
30
-
31
- <div id="vp_table" style="display:none; height:100%; overflow:auto;">
32
- <div style="width:100%; overflow:auto;">
33
- <table id="vp_table_tbl" style="border-collapse: collapse; width:100%; min-width: 520px;">
34
- <thead></thead>
35
- <tbody></tbody>
36
- </table>
37
- </div>
38
- </div>
39
- <div id="vp_sources" style="margin-top:10px;">
40
- <div id="vp_sources_container"
41
- style="display:grid; grid-template-columns: repeat( auto-fit, minmax(220px, 1fr) ); gap:10px;"></div>
42
- </div>
43
- </div>
44
-
45
- <script>
46
- (function () {
47
- var root = document.getElementById('view_panel_root');
48
- var viewTabsEl = document.getElementById('view_tabs');
49
- var splash = document.getElementById('view_panel_splash');
50
- var vpImage = document.getElementById('vp_image');
51
- var vpImageImg = document.getElementById('vp_image_img');
52
- var vpPdf = document.getElementById('vp_pdf');
53
- var vpPdfIframe = document.getElementById('vp_pdf_iframe');
54
- var vpText = document.getElementById('vp_text');
55
- var vpTextPre = document.getElementById('vp_text_pre');
56
- var vpJson = document.getElementById('vp_json');
57
- var vpJsonPre = document.getElementById('vp_json_pre');
58
- var vpTable = document.getElementById('vp_table');
59
- var vpTableTbl = document.getElementById('vp_table_tbl');
60
- var vpSources = document.getElementById('vp_sources');
61
- var vpSourcesContainer = document.getElementById('vp_sources_container');
62
- // Table incremental rendering state
63
- var tableState = { headers: [], rows: [], rendered: 0, pageSize: 200, isLoading: false, endReached: false };
64
- var tableScrollHandler = null;
65
-
66
- // --- Icons helpers (use public/sources-logos files) ---
67
- function getIconSrcForType(type) {
68
- var t = String(type || '').toLowerCase();
69
- function src(name) { return '/static/sources-logos/' + name; }
70
- if (!t) return src('database.svg');
71
- if (t.indexOf('folder') !== -1) return src('folder.svg');
72
- if (t === 'file') return src('file.svg');
73
- if (t.indexOf('image') !== -1 || t.indexOf('png') !== -1 || t.indexOf('jpg') !== -1 || t.indexOf('jpeg') !== -1) return src('picture.png');
74
- if (t.indexOf('csv') !== -1) return src('csv.svg');
75
- if (t.indexOf('xlsx') !== -1) return src('xlsx.svg');
76
- if (t.indexOf('xls') !== -1) return src('xls.svg');
77
- if (t.indexOf('excel') !== -1) return src('excel.svg');
78
- if (t.indexOf('json') !== -1) return src('json.png');
79
- if (t.indexOf('parquet') !== -1) return src('parquet.svg');
80
- if (t.indexOf('avro') !== -1) return src('avro.svg');
81
- if (t.indexOf('s3') !== -1) return src('s3.svg');
82
- if (t.indexOf('gcs') !== -1) return src('gcs.png');
83
- if (t.indexOf('azure_blob') !== -1 || t.indexOf('azure-blob') !== -1) return src('azure_blob.svg');
84
- if (t.indexOf('hdfs') !== -1) return src('hdfs.svg');
85
- if (t.indexOf('postgres') !== -1) return src('postgresql.svg');
86
- if (t.indexOf('mysql') !== -1) return src('mysql.svg');
87
- if (t.indexOf('mssql') !== -1 || t.indexOf('sqlserver') !== -1) return src('mssql.svg');
88
- if (t.indexOf('sqlite') !== -1) return src('sqlite.svg');
89
- if (t.indexOf('oracle') !== -1) return src('oracle.svg');
90
- if (t.indexOf('redshift') !== -1) return src('redshift.png');
91
- if (t.indexOf('snowflake') !== -1) return src('snowflake.png');
92
- if (t.indexOf('clickhouse') !== -1) return src('clickhouse.png');
93
- if (t.indexOf('duckdb') !== -1) return src('duckdb.png');
94
- if (t.indexOf('databricks') !== -1) return src('databricks.png');
95
- if (t.indexOf('cassandra') !== -1) return src('cassandra.svg');
96
- if (t.indexOf('elasticsearch') !== -1) return src('elasticsearch.svg');
97
- if (t.indexOf('mongodb') !== -1) return src('mongodb.svg');
98
- if (t.indexOf('cockroach') !== -1) return src('cockroach-db.png');
99
- if (t.indexOf('yugabyte') !== -1) return src('yugabyte-db.png');
100
- if (t.indexOf('questdb') !== -1) return src('questdb.png');
101
- if (t.indexOf('timescale') !== -1) return src('timescale.png');
102
- if (t.indexOf('alloy') !== -1) return src('alloy-db.png');
103
- if (t.indexOf('cloud sql') !== -1 || t.indexOf('cloud-sql') !== -1) return src('cloud-sql.png');
104
- if (t.indexOf('athena') !== -1) return src('amazon-athena.png');
105
- if (t.indexOf('rds') !== -1) return src('amazon-rds.png');
106
- if (t.indexOf('bigquery') !== -1) return src('bigquery.png');
107
- if (t.indexOf('synapse') !== -1) return src('azure-synapse-analytics.png');
108
- if (t.indexOf('single') !== -1 && t.indexOf('store') !== -1) return src('single-store.png');
109
- if (t.indexOf('starburst') !== -1) return src('starburst.png');
110
- if (t.indexOf('teradata') !== -1) return src('teradata.png');
111
- if (t.indexOf('hana') !== -1 || t.indexOf('sap') !== -1) return src('sap-hana.png');
112
- if (t.indexOf('sftp') !== -1) return src('sftp.png');
113
- if (t.indexOf('stream') !== -1) return src('stream.png');
114
- if (t.indexOf('api') !== -1) return src('api.svg');
115
- return src('database.svg');
116
- }
117
- function iconHtmlForType(type) {
118
- var src = getIconSrcForType(type);
119
- var title = String(type || '').toUpperCase();
120
- return '<img src="' + src + '" alt="' + title.replace(/"/g, '') + '" title="' + title.replace(/"/g, '') + '" style="width:16px;height:16px;object-fit:contain;margin-right:6px;vertical-align:middle;" />';
121
- }
122
-
123
- function hideAll() {
124
- [vpImage, vpPdf, vpText, vpJson, vpTable].forEach(function (el) { if (el) el.style.display = 'none'; });
125
- if (splash) splash.style.display = 'none';
126
- }
127
-
128
- function toObjectRowsFromItems(items) {
129
- // items: array of objects -> { headers: string[], rows: string[][] }
130
- if (!Array.isArray(items) || !items.length) return { headers: [], rows: [] };
131
- var headers = Object.keys(items[0]);
132
- var rows = items.map(function (it) { return headers.map(function (h) { var v = it[h]; return v == null ? '' : String(v); }); });
133
- return { headers: headers, rows: rows };
134
- }
135
-
136
- function toRowsFromCsv(csv) {
137
- // naive CSV split (no advanced quoting); acceptable for simple cases
138
- var lines = String(csv || '').split(/\r?\n/).filter(Boolean);
139
- var rows = lines.map(function (line) { return line.split(',').map(function (cell) { return cell.trim(); }); });
140
- var headers = rows.length ? rows[0] : [];
141
- var body = rows.length > 1 ? rows.slice(1) : [];
142
- return { headers: headers, rows: body };
143
- }
144
-
145
- function appendTableRows(count) {
146
- var tbody = vpTableTbl.querySelector('tbody');
147
- var start = tableState.rendered;
148
- var end = Math.min(start + (count != null ? count : tableState.pageSize), tableState.rows.length);
149
- for (var i = start; i < end; i++) {
150
- var r = tableState.rows[i];
151
- var tr = document.createElement('tr');
152
- r.forEach(function (c) {
153
- var td = document.createElement('td');
154
- td.textContent = c == null ? '' : String(c);
155
- td.style.borderBottom = '1px solid #f3f4f6';
156
- td.style.padding = '6px 8px';
157
- tr.appendChild(td);
158
- });
159
- tbody.appendChild(tr);
160
- }
161
- tableState.rendered = end;
162
- if (end >= tableState.rows.length) { tableState.endReached = true; }
163
- }
164
- function setupTableIncrementalRendering(data) {
165
- // Normalize data to headers/rows
166
- var headers = [];
167
- var rows = [];
168
- if (data && Array.isArray(data.headers) && Array.isArray(data.rows)) {
169
- headers = data.headers; rows = data.rows;
170
- } else if (data && Array.isArray(data.items)) {
171
- var obj = toObjectRowsFromItems(data.items);
172
- headers = obj.headers; rows = obj.rows;
173
- } else if (data && typeof data.csv === 'string') {
174
- var parsed = toRowsFromCsv(data.csv);
175
- headers = parsed.headers; rows = parsed.rows;
176
- }
177
- // Reset state
178
- tableState.headers = headers || [];
179
- tableState.rows = Array.isArray(rows) ? rows : [];
180
- tableState.rendered = 0;
181
- tableState.endReached = false;
182
- // Build header
183
- var thead = vpTableTbl.querySelector('thead');
184
- var tbody = vpTableTbl.querySelector('tbody');
185
- thead.innerHTML = '';
186
- tbody.innerHTML = '';
187
- if (tableState.headers.length) {
188
- var trh = document.createElement('tr');
189
- tableState.headers.forEach(function (h) {
190
- var th = document.createElement('th');
191
- th.textContent = String(h);
192
- th.style.textAlign = 'left';
193
- th.style.borderBottom = '1px solid #e5e7eb';
194
- th.style.padding = '6px 8px';
195
- th.style.position = 'sticky';
196
- th.style.top = '0';
197
- th.style.background = '#ffffff';
198
- trh.appendChild(th);
199
- });
200
- thead.appendChild(trh);
201
- }
202
- // Initial 200-row preview
203
- appendTableRows(tableState.pageSize);
204
- // Attach scroll listener for infinite scroll
205
- if (tableScrollHandler && vpTable) { try { vpTable.removeEventListener('scroll', tableScrollHandler); } catch (e) { } }
206
- tableScrollHandler = function () {
207
- if (!vpTable || tableState.endReached || tableState.isLoading) return;
208
- var remaining = (vpTable.scrollHeight - vpTable.scrollTop - vpTable.clientHeight);
209
- if (remaining < 200) {
210
- tableState.isLoading = true;
211
- // Lazy append next chunk after a frame to keep UI responsive
212
- requestAnimationFrame(function () {
213
- appendTableRows(tableState.pageSize);
214
- tableState.isLoading = false;
215
- });
216
- }
217
- };
218
- if (vpTable) vpTable.addEventListener('scroll', tableScrollHandler);
219
- }
220
- function renderTable(data) { setupTableIncrementalRendering(data); }
221
-
222
- function pretty(obj) {
223
- try { return JSON.stringify(obj, null, 2); } catch (e) { return String(obj); }
224
- }
225
-
226
- function setView(conf) {
227
- conf = conf || {};
228
- var type = (conf.type || '').toLowerCase();
229
- hideAll();
230
- if (type === 'image') {
231
- var src = conf.src;
232
- if (conf.file instanceof Blob) { src = URL.createObjectURL(conf.file); }
233
- if (vpImageImg) vpImageImg.src = src || '';
234
- if (vpImage) vpImage.style.display = 'block';
235
- return;
236
- }
237
- if (type === 'pdf') {
238
- var psrc = conf.src;
239
- if (conf.file instanceof Blob) { psrc = URL.createObjectURL(conf.file); }
240
- if (vpPdfIframe) vpPdfIframe.src = psrc || '';
241
- if (vpPdf) vpPdf.style.display = 'block';
242
- return;
243
- }
244
- if (type === 'text') {
245
- if (vpTextPre) vpTextPre.textContent = conf.text || '';
246
- if (vpText) vpText.style.display = 'block';
247
- return;
248
- }
249
- if (type === 'json') {
250
- var raw = conf.data;
251
- var out = (typeof raw === 'string') ? raw : pretty(raw);
252
- if (vpJsonPre) vpJsonPre.textContent = out || '';
253
- if (vpJson) vpJson.style.display = 'block';
254
- return;
255
- }
256
- if (type === 'table') {
257
- renderTable(conf || {});
258
- if (vpTable) vpTable.style.display = 'block';
259
- return;
260
- }
261
- // fallback
262
- if (splash) splash.style.display = 'flex';
263
- }
264
-
265
- // Expose a simple API to other panels
266
- function reloadView() { try { renderViewTabs(); loadSources(); loadFromUrl(); } catch (e) { } }
267
- window.StudioViewPanel = { setView: setView, reload: reloadView };
268
-
269
- function readViewTabs() {
270
- try { return JSON.parse(sessionStorage.getItem('studio_view_tabs') || '[]'); } catch (e) { return []; }
271
- }
272
- function writeViewTabs(list) {
273
- try { sessionStorage.setItem('studio_view_tabs', JSON.stringify(Array.isArray(list) ? list : [])); } catch (e) { }
274
- }
275
- function readViewLabels() {
276
- try { return JSON.parse(sessionStorage.getItem('studio_view_labels') || '{}'); } catch (e) { return {}; }
277
- }
278
- function writeViewLabels(map) {
279
- try { sessionStorage.setItem('studio_view_labels', JSON.stringify(map || {})); } catch (e) { }
280
- }
281
- function readViewTypes() {
282
- try { return JSON.parse(sessionStorage.getItem('studio_view_types') || '{}'); } catch (e) { return {}; }
283
- }
284
- function writeViewTypes(map) {
285
- try { sessionStorage.setItem('studio_view_types', JSON.stringify(map || {})); } catch (e) { }
286
- }
287
- function currentSourceId() { try { return new URLSearchParams(window.location.search).get('source_id') || ''; } catch (e) { return ''; } }
288
- function ensureViewTab(id) {
289
- if (!id) return;
290
- var tabs = readViewTabs();
291
- if (tabs.indexOf(id) === -1) { tabs.unshift(id); writeViewTabs(tabs); }
292
- renderViewTabs();
293
- }
294
- function renderViewTabs() {
295
- var root = viewTabsEl; if (!root) return;
296
- root.innerHTML = '';
297
- // Plus button on the left: unset source_id and open/focus sources list
298
- var plus = document.createElement('button');
299
- plus.title = 'Ouvrir la liste des sources';
300
- plus.textContent = '+';
301
- plus.style.cssText = 'border:1px solid #e5e7eb; background:#ffffff; color:#374151; padding:4px 8px; border-radius:6px; cursor:pointer;';
302
- plus.addEventListener('click', function () {
303
- try {
304
- // Unset source_id in URL
305
- var p = new URLSearchParams(window.location.search);
306
- p.delete('source_id');
307
- var newUrl = window.location.pathname + (p.toString() ? ('?' + p.toString()) : '');
308
- window.history.replaceState({}, '', newUrl);
309
- // Hide any current preview
310
- hideAll();
311
- // Show sources list
312
- if (vpSources) { vpSources.style.display = 'block'; }
313
- // Scroll and highlight briefly
314
- if (vpSources) {
315
- vpSources.scrollIntoView({ behavior: 'smooth', block: 'start' });
316
- var prev = vpSources.style.boxShadow;
317
- vpSources.style.boxShadow = '0 0 0 2px rgba(65,105,225,0.35)';
318
- setTimeout(function () { vpSources.style.boxShadow = prev || ''; }, 1200);
319
- }
320
- renderViewTabs();
321
- loadSources();
322
- } catch (e) { }
323
- });
324
- root.appendChild(plus);
325
- // (project clear UI removed; handled in context-panel)
326
- // Tabs for recently viewed sources
327
- var tabs = readViewTabs();
328
- var selectedId = currentSourceId();
329
- var labels = readViewLabels();
330
- var types = readViewTypes();
331
- function removeViewTab(id) {
332
- var list = readViewTabs().filter(function (t) { return t !== id; });
333
- writeViewTabs(list);
334
- if (id === selectedId) {
335
- if (list.length) {
336
- var p = new URLSearchParams(window.location.search);
337
- p.set('source_id', list[0]);
338
- var newUrl = window.location.pathname + '?' + p.toString();
339
- window.history.replaceState({}, '', newUrl);
340
- loadSources();
341
- loadFromUrl();
342
- } else {
343
- var p2 = new URLSearchParams(window.location.search);
344
- p2.delete('source_id');
345
- var newUrl2 = window.location.pathname + (p2.toString() ? ('?' + p2.toString()) : '');
346
- window.history.replaceState({}, '', newUrl2);
347
- loadSources();
348
- loadFromUrl();
349
- }
350
- }
351
- renderViewTabs();
352
- }
353
- tabs.forEach(function (id) {
354
- var container = document.createElement('div');
355
- container.style.cssText = 'display:inline-flex; align-items:center; gap:4px; border:1px solid #e5e7eb; background:' + (id === selectedId ? '#eef2ff' : '#ffffff') + '; color:#111827; padding:2px 4px; border-radius:6px; white-space:nowrap;';
356
- var labelBtn = document.createElement('button');
357
- var label = (labels && labels[id]) ? String(labels[id]) : ('Source ' + id);
358
- var typeForId = (types && types[id]) ? String(types[id]) : '';
359
- var icon = iconHtmlForType(typeForId);
360
- labelBtn.innerHTML = icon + '<span>' + label.replace(/</g, '&lt;') + '</span>';
361
- labelBtn.title = label;
362
- labelBtn.style.cssText = 'background:transparent; border:0; color:inherit; padding:2px 4px; cursor:pointer;';
363
- labelBtn.addEventListener('click', function () {
364
- var p = new URLSearchParams(window.location.search);
365
- p.set('source_id', id);
366
- var newUrl = window.location.pathname + '?' + p.toString();
367
- window.history.replaceState({}, '', newUrl);
368
- loadSources();
369
- loadFromUrl();
370
- renderViewTabs();
371
- });
372
- var closeBtn = document.createElement('button');
373
- closeBtn.textContent = '×';
374
- closeBtn.title = 'Fermer';
375
- closeBtn.style.cssText = 'background:transparent; border:0; color:#6b7280; padding:2px 4px; cursor:pointer;';
376
- closeBtn.addEventListener('click', function (ev) { ev.stopPropagation(); removeViewTab(id); });
377
- container.appendChild(labelBtn);
378
- container.appendChild(closeBtn);
379
- root.appendChild(container);
380
- });
381
- }
382
-
383
- function readUrlParam(key) { try { return new URLSearchParams(window.location.search).get(key) || ''; } catch (e) { return ''; } }
384
- function showError(message) {
385
- try {
386
- hideAll();
387
- var err = document.getElementById('vp_error');
388
- if (err) { err.textContent = String(message || 'Error'); err.style.display = 'block'; }
389
- if (vpText) vpText.style.display = 'none';
390
- } catch (e) { /* noop */ }
391
- }
392
- async function loadFromUrl() {
393
- var srcId = readUrlParam('source_id');
394
- // Hide sources list if a source is selected
395
- try { if (vpSources) vpSources.style.display = srcId ? 'none' : 'block'; } catch (e) { }
396
- if (!srcId) { try { hideAll(); } catch (e) { } return; }
397
- try {
398
- // Always fetch full preview; render 200 rows first, then lazy-load more client-side
399
- var url = '/sources/preview?source_id=' + encodeURIComponent(srcId) + '&verbose=1';
400
- console.log('[ViewPanel] fetching preview:', url);
401
- var r = await fetch(url);
402
- var j = await r.json();
403
- if (j && j.ok && j.view) {
404
- var err = document.getElementById('vp_error'); if (err) { err.style.display = 'none'; err.textContent = ''; }
405
- if (j.debug) console.log('[ViewPanel] debug:', j.debug);
406
- setView(j.view);
407
- ensureViewTab(srcId);
408
- } else {
409
- console.warn('[ViewPanel] preview error:', j);
410
- showError((j && (j.message || j.error && (j.error.detail || j.error.message))) || 'Preview failed');
411
- }
412
- } catch (e) {
413
- console.error('[ViewPanel] preview request failed', e);
414
- showError('Preview request failed');
415
- }
416
- }
417
- function normalizeSources(j) {
418
- try {
419
- if (!j) return [];
420
- if (Array.isArray(j)) return j;
421
- if (Array.isArray(j.items)) return j.items;
422
- if (Array.isArray(j.data)) return j.data;
423
- if (Array.isArray(j.results)) return j.results;
424
- if (j.data && Array.isArray(j.data.items)) return j.data.items;
425
- if (Array.isArray(j.sources)) return j.sources;
426
- if (typeof j === 'object' && (j.id != null || j.name != null)) return [j];
427
- } catch (e) { }
428
- return [];
429
- }
430
- function renderSources(items) {
431
- var root = vpSourcesContainer; if (!root) return;
432
- root.innerHTML = '';
433
- if (!Array.isArray(items) || !items.length) {
434
- var e = document.createElement('div');
435
- e.className = 'muted';
436
- e.textContent = 'No sources';
437
- root.appendChild(e);
438
- return;
439
- }
440
- var params = new URLSearchParams(window.location.search);
441
- var selectedId = params.get('source_id');
442
- items.forEach(function (it) {
443
- var id = String(it.id || it.source_id || '');
444
- var name = it.name || (it.source && it.source.name) || ('Source ' + id);
445
- var type = it.type || (it.source && it.source.type) || '';
446
- var localPresent = !!it.local_present;
447
- var localValidate = (it.local_validate || '').toLowerCase();
448
- var isInvalid = localValidate && localValidate !== 'valid';
449
- var disabled = (!localPresent) || isInvalid;
450
- var hoverMsg = '';
451
- if (!localPresent) {
452
- hoverMsg = 'Configuration de la source non disponible localement';
453
- } else if (isInvalid) {
454
- hoverMsg = 'Source non accéssible';
455
- }
456
- var card = document.createElement('div');
457
- card.className = 'card';
458
- card.style.cursor = disabled ? 'not-allowed' : 'pointer';
459
- card.style.padding = '8px 10px';
460
- card.style.border = '1px solid #e5e7eb';
461
- card.style.borderRadius = '8px';
462
- card.style.background = '#ffffff';
463
- if (hoverMsg) card.title = hoverMsg;
464
- if (disabled) {
465
- card.style.opacity = '0.5';
466
- card.style.filter = 'grayscale(100%)';
467
- }
468
- var icon = iconHtmlForType(type);
469
- card.innerHTML = '<div style="font-weight:600; color:#111827; display:flex; align-items:center; gap:6px;">' + icon + '<span>' + name.replace(/</g, '&lt;') + '</span></div>' +
470
- '<div class="muted" style="font-size:12px;">' + (type ? ('Type: ' + type) : '') + '</div>' +
471
- '<div class="muted" style="font-size:12px;">#' + id + '</div>';
472
- if (selectedId && id === selectedId) {
473
- card.style.boxShadow = '0 0 0 2px rgba(65,105,225,0.35)';
474
- }
475
- if (!disabled) {
476
- card.addEventListener('click', function () {
477
- var p = new URLSearchParams(window.location.search);
478
- p.set('source_id', id);
479
- var newUrl = window.location.pathname + '?' + p.toString();
480
- window.history.replaceState({}, '', newUrl);
481
- renderSources(items);
482
- loadFromUrl();
483
- });
484
- }
485
- root.appendChild(card);
486
- });
487
- }
488
- async function loadSources() {
489
- try {
490
- var projectId = readUrlParam('project_id');
491
- var url = '/studio/sources' + (projectId ? ('?project_id=' + encodeURIComponent(projectId)) : '');
492
- var r = await fetch(url);
493
- var j = await r.json();
494
- var items = normalizeSources(j && (j.items != null ? j.items : j));
495
- // Extra client-side filter by project_id as a safeguard
496
- if (projectId) {
497
- items = items.filter(function (it) {
498
- try {
499
- var pid = it.project_id != null ? String(it.project_id) : (it.project && it.project.id != null ? String(it.project.id) : '');
500
- return pid ? (pid === String(projectId)) : true;
501
- } catch (e) { return true; }
502
- });
503
- }
504
- // Build and cache labels map for view tabs
505
- try {
506
- var labelsMap = readViewLabels();
507
- var typesMap = readViewTypes();
508
- items.forEach(function (it) {
509
- var id = String(it.id || it.source_id || '');
510
- var name = it.name || (it.source && it.source.name) || ('Source ' + id);
511
- var type = it.type || (it.source && it.source.type) || '';
512
- if (id) labelsMap[id] = String(name);
513
- if (id) typesMap[id] = String(type);
514
- });
515
- writeViewLabels(labelsMap);
516
- writeViewTypes(typesMap);
517
- // Re-render tabs to reflect labels instead of IDs
518
- try { renderViewTabs(); } catch (e) { }
519
- } catch (e) { }
520
- renderSources(items);
521
- } catch (e) {
522
- renderSources([]);
523
- }
524
- }
525
- document.addEventListener('DOMContentLoaded', function () { renderViewTabs(); loadSources(); loadFromUrl(); });
526
- window.addEventListener('popstate', function () { renderViewTabs(); loadSources(); loadFromUrl(); });
527
- // React to project/issue changes from context-panel by listening to our own dispatched popstate
528
- })();
529
- </script>
@@ -1,58 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: qalita
3
- Version: 2.3.1
4
- Summary: QALITA Platform Command Line Interface
5
- License-File: LICENSE
6
- Author: QALITA SAS
7
- Author-email: contact@qalita.io
8
- Requires-Python: >=3.10,<4.0
9
- Classifier: Development Status :: 5 - Production/Stable
10
- Classifier: Environment :: Console
11
- Classifier: Intended Audience :: Developers
12
- Classifier: Intended Audience :: Information Technology
13
- Classifier: License :: Other/Proprietary License
14
- Classifier: Natural Language :: English
15
- Classifier: Operating System :: Unix
16
- Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.10
18
- Classifier: Programming Language :: Python :: 3.11
19
- Classifier: Programming Language :: Python :: 3.12
20
- Classifier: Programming Language :: Python :: 3.13
21
- Classifier: Programming Language :: Python :: 3.14
22
- Classifier: Topic :: Software Development :: Quality Assurance
23
- Requires-Dist: azure-storage-blob (>=12.19.1,<13.0.0)
24
- Requires-Dist: boto3 (>=1.34.81,<2.0.0)
25
- Requires-Dist: click (>=8.1.3,<9.0.0)
26
- Requires-Dist: croniter (>=1.4.1,<2.0.0)
27
- Requires-Dist: cryptography (>=44.0.1,<45.0.0)
28
- Requires-Dist: flask (>=3.0.3,<4.0.0)
29
- Requires-Dist: google-cloud-storage (>=2.16.0,<3.0.0)
30
- Requires-Dist: hdfs (>=2.7.3,<3.0.0)
31
- Requires-Dist: loguru (>=0.7.0,<0.8.0)
32
- Requires-Dist: openpyxl (>=3.1.5,<4.0.0)
33
- Requires-Dist: oracledb (>=2.5.0,<3.0.0)
34
- Requires-Dist: paramiko (>=3.4.0,<4.0.0)
35
- Requires-Dist: poetry (>=1.7.1,<2.0.0)
36
- Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0)
37
- Requires-Dist: pymongo (>=4.6.3,<5.0.0)
38
- Requires-Dist: pymysql (>=1.1.0,<2.0.0)
39
- Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
40
- Requires-Dist: requests (>=2.31.0,<3.0.0)
41
- Requires-Dist: semver (>=3.0.1,<4.0.0)
42
- Requires-Dist: setuptools-rust (>=1.8.1,<2.0.0)
43
- Requires-Dist: tabulate (>=0.9.0,<0.10.0)
44
- Requires-Dist: toml (>=0.10.2,<0.11.0)
45
- Requires-Dist: waitress (==3.0.2)
46
- Description-Content-Type: text/markdown
47
-
48
- # QALITA Command Line Interface (CLI)
49
-
50
- <div style="text-align:center;">
51
- <img width="250px" height="auto" src="https://cloud.platform.qalita.io/logo.svg" style="max-width:250px;"/>
52
- </div>
53
-
54
- QALITA Command Line Interface (CLI) is a tool intended to be used by Data Engineers who setup's QALITA Platform's agents, sources and assets.
55
-
56
- It gives easy to use command to help them make an up & running qalita platform's environment in no time.
57
-
58
- Find the full documentation [in the online documentation](https://doc.qalita.io/docs/cli)