panther 4.3.7__py3-none-any.whl → 5.0.0b2__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 (59) hide show
  1. panther/__init__.py +1 -1
  2. panther/_load_configs.py +78 -64
  3. panther/_utils.py +1 -1
  4. panther/app.py +126 -60
  5. panther/authentications.py +26 -9
  6. panther/base_request.py +27 -2
  7. panther/base_websocket.py +26 -27
  8. panther/cli/create_command.py +1 -0
  9. panther/cli/main.py +19 -27
  10. panther/cli/monitor_command.py +8 -4
  11. panther/cli/template.py +11 -6
  12. panther/cli/utils.py +3 -2
  13. panther/configs.py +7 -9
  14. panther/db/cursor.py +23 -7
  15. panther/db/models.py +26 -19
  16. panther/db/queries/base_queries.py +1 -1
  17. panther/db/queries/mongodb_queries.py +177 -13
  18. panther/db/queries/pantherdb_queries.py +5 -5
  19. panther/db/queries/queries.py +1 -1
  20. panther/events.py +10 -4
  21. panther/exceptions.py +24 -2
  22. panther/generics.py +2 -2
  23. panther/main.py +90 -117
  24. panther/middlewares/__init__.py +1 -1
  25. panther/middlewares/base.py +15 -19
  26. panther/middlewares/monitoring.py +42 -0
  27. panther/openapi/__init__.py +1 -0
  28. panther/openapi/templates/openapi.html +27 -0
  29. panther/openapi/urls.py +5 -0
  30. panther/openapi/utils.py +167 -0
  31. panther/openapi/views.py +101 -0
  32. panther/pagination.py +1 -1
  33. panther/panel/middlewares.py +10 -0
  34. panther/panel/templates/base.html +14 -0
  35. panther/panel/templates/create.html +21 -0
  36. panther/panel/templates/create.js +1270 -0
  37. panther/panel/templates/detail.html +55 -0
  38. panther/panel/templates/home.html +9 -0
  39. panther/panel/templates/home.js +30 -0
  40. panther/panel/templates/login.html +47 -0
  41. panther/panel/templates/sidebar.html +13 -0
  42. panther/panel/templates/table.html +73 -0
  43. panther/panel/templates/table.js +339 -0
  44. panther/panel/urls.py +10 -5
  45. panther/panel/utils.py +98 -0
  46. panther/panel/views.py +143 -0
  47. panther/request.py +3 -0
  48. panther/response.py +91 -53
  49. panther/routings.py +7 -2
  50. panther/serializer.py +1 -1
  51. panther/utils.py +34 -26
  52. panther/websocket.py +3 -0
  53. {panther-4.3.7.dist-info → panther-5.0.0b2.dist-info}/METADATA +19 -17
  54. panther-5.0.0b2.dist-info/RECORD +75 -0
  55. {panther-4.3.7.dist-info → panther-5.0.0b2.dist-info}/WHEEL +1 -1
  56. panther-4.3.7.dist-info/RECORD +0 -57
  57. {panther-4.3.7.dist-info → panther-5.0.0b2.dist-info}/entry_points.txt +0 -0
  58. {panther-4.3.7.dist-info → panther-5.0.0b2.dist-info}/licenses/LICENSE +0 -0
  59. {panther-4.3.7.dist-info → panther-5.0.0b2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,55 @@
1
+ {% extends "base.html" %} {% block content %}
2
+ <div class="container mx-auto px-4 py-8">
3
+ <div class="flex justify-between items-center mb-8">
4
+ <h1 class="text-2xl font-bold">Update Record</h1>
5
+ <button
6
+ onclick="redirectToTable()"
7
+ class="px-4 py-2 bg-gray-800 rounded hover:bg-gray-700"
8
+ >
9
+ Back to List
10
+ </button>
11
+ </div>
12
+
13
+ <form id="updateForm" class="mt-6">
14
+ <div
15
+ id="dynamicInputs"
16
+ class="bg-gray-800 border-gray-400 rounded-lg p-6 shadow-lg space-y-4"
17
+ ></div>
18
+ <div class="flex justify-start mt-6 space-x-4">
19
+ <button
20
+ type="submit"
21
+ class="px-6 py-2 bg-blue-600 rounded hover:bg-blue-700 text-white"
22
+ >
23
+ Update
24
+ </button>
25
+ <button
26
+ type="button"
27
+ id="deleteButton"
28
+ class="px-6 py-2 bg-red-600 rounded hover:bg-red-700 text-white"
29
+ >
30
+ Delete
31
+ </button>
32
+ </div>
33
+ </form>
34
+ </div>
35
+
36
+ <script>
37
+ const data = JSON.parse(`{{data|tojson|safe}}`);
38
+ console.log("Data passed to the form:", data); // Debugging log
39
+ const isUpdate = true;
40
+ const existingData = data;
41
+ function redirectToTable() {
42
+ const currentUrl = window.location.pathname;
43
+ const urlParts = currentUrl.split("/").filter((part) => part !== "");
44
+ urlParts.pop();
45
+ const redirectUrl = "/" + urlParts.join("/") + "/";
46
+
47
+ console.log("Redirecting to:", redirectUrl);
48
+
49
+ window.location.href = redirectUrl;
50
+
51
+ }
52
+ {% include "create.js" %}
53
+
54
+ </script>
55
+ {% endblock %}
@@ -0,0 +1,9 @@
1
+ {% extends "base.html" %} {% block content %}
2
+ <div class="flex gap-4">
3
+ {% include "sidebar.html" %}
4
+ <table class="w-full bg-gray-800 rounded overflow-hidden"></table>
5
+ </div>
6
+ <script>
7
+ {% include "home.js" %}
8
+ </script>
9
+ {% endblock %}
@@ -0,0 +1,30 @@
1
+ function getCurrentTableIndex() {
2
+ const path = window.location.pathname;
3
+ const match = path.match(/\/admin\/(\d+)/);
4
+ return match ? parseInt(match[1]) : 0;
5
+ }
6
+
7
+ function selectTable(element) {
8
+ const index = element.dataset.index;
9
+ // Always trigger a page reload even if it's the same index
10
+ window.location.href = `/admin/${index}/`;
11
+ }
12
+
13
+ function setActiveTableFromUrl() {
14
+ const currentIndex = getCurrentTableIndex();
15
+ const tableItems = document.querySelectorAll('.table-item');
16
+
17
+ tableItems.forEach((item) => {
18
+ item.classList.remove('bg-blue-600');
19
+ item.classList.add('bg-gray-700');
20
+
21
+ if (parseInt(item.dataset.index) === currentIndex) {
22
+ item.classList.remove('bg-gray-700');
23
+ item.classList.add('bg-blue-600');
24
+ }
25
+ });
26
+ }
27
+
28
+ document.addEventListener('DOMContentLoaded', () => {
29
+ setActiveTableFromUrl();
30
+ });
@@ -0,0 +1,47 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block content %}
4
+ <div class="flex items-center justify-center min-h-screen">
5
+ <div class="bg-gray-800 p-6 rounded-lg shadow-md w-full max-w-sm border border-gray-700">
6
+ <h2 class="text-xl font-semibold mb-6 text-center">Login</h2>
7
+
8
+ {% if error %}
9
+ <div class="mb-4 p-3 text-sm text-red-600 bg-red-100 border border-red-400 rounded-lg">
10
+ {{ error }}
11
+ </div>
12
+ {% endif %}
13
+
14
+ <form action="" method="POST" class="space-y-4">
15
+ <!-- Username Field -->
16
+ <div>
17
+ <label for="username" class="block text-sm font-medium mb-2">Username:</label>
18
+ <input
19
+ type="text"
20
+ id="username"
21
+ name="username"
22
+ required
23
+ class="w-full p-2 bg-gray-700 rounded-lg border border-gray-600 text-white focus:ring-2 focus:ring-blue-500 focus:outline-none"
24
+ />
25
+ </div>
26
+ <!-- Password Field -->
27
+ <div>
28
+ <label for="password" class="block text-sm font-medium mb-2">Password:</label>
29
+ <input
30
+ type="password"
31
+ id="password"
32
+ name="password"
33
+ required
34
+ class="w-full p-2 bg-gray-700 rounded-lg border border-gray-600 text-white focus:ring-2 focus:ring-blue-500 focus:outline-none"
35
+ />
36
+ </div>
37
+ <!-- Submit Button -->
38
+ <button
39
+ type="submit"
40
+ class="w-full bg-blue-600 hover:bg-blue-500 text-white py-2 px-4 rounded-lg font-semibold transition-colors"
41
+ >
42
+ Login
43
+ </button>
44
+ </form>
45
+ </div>
46
+ </div>
47
+ {% endblock %}
@@ -0,0 +1,13 @@
1
+
2
+ <aside class="w-64 bg-gray-800 p-4 border-gray-700 shrink-0 rounded">
3
+ <h2 class="text-lg font-semibold mb-4">Available Tables</h2>
4
+ <div class="space-y-2">
5
+ {% for table in tables %}
6
+ <div class="table-item p-3 rounded-lg bg-gray-700 hover:bg-gray-600 cursor-pointer transition-colors"
7
+ data-index="{{loop.index0}}" onclick="selectTable(this)">
8
+ <div class="text-sm font-medium">{{table.name}}</div>
9
+ <div class="text-xs text-gray-400">{{table.module}}</div>
10
+ </div>
11
+ {% endfor %}
12
+ </div>
13
+ </aside>
@@ -0,0 +1,73 @@
1
+ {% extends "base.html" %} {% block content %}
2
+ <div class="flex items-start gap-4">
3
+ <aside class="w-64 bg-gray-800 p-4 border-gray-700 shrink-0 rounded">
4
+ <h2 class="text-lg font-semibold mb-4">Available Tables</h2>
5
+ <div class="space-y-2">
6
+ {% for table in tables %}
7
+ <div
8
+ class="table-item p-3 rounded-lg bg-gray-700 hover:bg-gray-600 cursor-pointer transition-colors flex justify-between items-center"
9
+ data-index="{{loop.index0}}"
10
+ onclick="selectTable(this, event)"
11
+ >
12
+ <div>
13
+ <div class="text-sm font-medium">{{table.name}}</div>
14
+ <div class="text-xs text-gray-400">{{table.module}}</div>
15
+ </div>
16
+ <button
17
+ class="add-record-btn hidden p-2 text-xs flex bg-green-600 text-white rounded-full hover:bg-green-700 transition-colors duration-200"
18
+ onclick="goToCreatePage(event)"
19
+ title="Create new record"
20
+ >
21
+ Add
22
+ <svg
23
+ class="w-4 h-4"
24
+ fill="none"
25
+ stroke="currentColor"
26
+ viewBox="0 0 24 24"
27
+ xmlns="http://www.w3.org/2000/svg"
28
+ >
29
+ <path
30
+ stroke-linecap="round"
31
+ stroke-linejoin="round"
32
+ stroke-width="2"
33
+ d="M12 6v6m0 0v6m0-6h6m-6 0H6"
34
+ ></path>
35
+ </svg>
36
+ </button>
37
+ </div>
38
+ {% endfor %}
39
+ </div>
40
+
41
+ </aside>
42
+
43
+ <div>
44
+ <table class="w-full bg-gray-800 rounded overflow-hidden">
45
+ <thead class="bg-gray-700" id="tableHead"></thead>
46
+ <tbody id="tableBody">
47
+ {% for record in records %}
48
+ <tr class="record-row border-t border-gray-700 hover:bg-gray-750">
49
+ <td class="record-data hidden">{{record}}</td>
50
+ </tr>
51
+ {% endfor %}
52
+ </tbody>
53
+ <tfoot
54
+ id="paginationControls"
55
+ class="my-4 flex-grow flex mx-[100%] gap-4 justify-center w-full min-w-80"
56
+ ></tfoot>
57
+ </table>
58
+ </div>
59
+ </div>
60
+ <style>
61
+ details[open] summary svg {
62
+ transform: rotate(180deg);
63
+ }
64
+
65
+ details summary::-webkit-details-marker {
66
+ display: none;
67
+ }
68
+ </style>
69
+ <script>
70
+ {% include "table.js" %}
71
+ </script>
72
+
73
+ {% endblock %}
@@ -0,0 +1,339 @@
1
+ const fields = JSON.parse(`{{fields|tojson|safe}}`);
2
+ const fieldsObject = fields.fields;
3
+ const fieldsArray = Object.entries(fieldsObject).map(([key, value]) => ({
4
+ title: value.title || key,
5
+ type: value.type || [],
6
+ required: value.required || false,
7
+ }));
8
+
9
+ function pythonToJSON(str) {
10
+ str = str.replace(/datetime\.datetime\(([^)]+)\)/g, (match, contents) => {
11
+ const parts = contents.split(",").map((part) => part.trim());
12
+ if (parts.length >= 6) {
13
+ return `"${parts[0]}-${parts[1].padStart(2, "0")}-${parts[2].padStart(
14
+ 2,
15
+ "0"
16
+ )} ${parts[3].padStart(2, "0")}:${parts[4].padStart(
17
+ 2,
18
+ "0"
19
+ )}:${parts[5].padStart(2, "0")}"`;
20
+ }
21
+ return '"Invalid datetime"';
22
+ });
23
+
24
+ str = str.replace(/tzinfo=\)/g, "tzinfo=None)");
25
+ return str
26
+ .replace(/'/g, '"')
27
+ .replace(/False/g, "false")
28
+ .replace(/True/g, "true")
29
+ .replace(/None/g, "null");
30
+ }
31
+ function goToCreatePage() {
32
+ // Get the current URL without any trailing slash
33
+ const currentUrl = window.location.href.replace(/\/+$/, "");
34
+ // Navigate to the current URL + /create
35
+ window.location.href = `${currentUrl}/create`;
36
+ }
37
+
38
+ function getDataType(value) {
39
+ if (value === null) return "null";
40
+ if (Array.isArray(value)) return "array";
41
+ return typeof value;
42
+ }
43
+
44
+ let allRecords = [];
45
+ function initializeRecords() {
46
+ if (allRecords.length === 0) {
47
+ try {
48
+ allRecords = Array.from(document.querySelectorAll(".record-data")).map(
49
+ (item) => {
50
+ try {
51
+ return JSON.parse(pythonToJSON(item.textContent.trim()));
52
+ } catch (e) {
53
+ console.error("Error parsing record:", e);
54
+ return {};
55
+ }
56
+ }
57
+ );
58
+ } catch (e) {
59
+ console.error("Error initializing records:", e);
60
+ allRecords = [];
61
+ }
62
+ }
63
+ }
64
+
65
+ function formatValue(value, type) {
66
+ if (value === null) return '<span class="text-gray-400">null</span>';
67
+
68
+ switch (type) {
69
+ case "array":
70
+ return `
71
+ <div class="w-full">
72
+ <details class="bg-gray-700 rounded-lg max-w-[300px]">
73
+ <summary class="cursor-pointer px-4 py-2 text-sm font-medium text-gray-300 hover:bg-gray-600 rounded-lg flex items-center justify-between">
74
+ <span>Array (${value.length} items)</span>
75
+ <svg class="w-4 h-4 transition-transform duration-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
76
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
77
+ </svg>
78
+ </summary>
79
+ <div class="px-4 py-2 border-t border-gray-600">
80
+ ${value
81
+ .map(
82
+ (item, index) => `
83
+ <div class="py-1 text-sm text-gray-300">
84
+ <span class="text-gray-400">[${index}]:</span>
85
+ ${formatValue(item, getDataType(item))}
86
+ </div>
87
+ `
88
+ )
89
+ .join("")}
90
+ </div>
91
+ </details>
92
+ </div>
93
+ `;
94
+ case "object":
95
+ if (value === null) {
96
+ return '<span class="text-gray-400">null</span>';
97
+ }
98
+ return `
99
+ <div class="w-full max-w-[300px]">
100
+ <details class="bg-gray-700 rounded-lg">
101
+ <summary class="cursor-pointer px-4 py-2 text-sm font-medium text-gray-300 hover:bg-gray-600 rounded-lg flex items-center justify-between">
102
+ <span>Object (${Object.keys(value).length} props)</span>
103
+ <svg class="w-4 h-4 transition-transform duration-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
104
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
105
+ </svg>
106
+ </summary>
107
+ <div class="px-4 py-2 border-t border-gray-600">
108
+ ${Object.entries(value)
109
+ .map(
110
+ ([key, val]) => `
111
+ <div class="py-1 text-sm text-gray-300">
112
+ <span class="text-gray-400">${key}:</span>
113
+ ${formatValue(val, getDataType(val))}
114
+ </div>
115
+ `
116
+ )
117
+ .join("")}
118
+ </div>
119
+ </details>
120
+ </div>
121
+ `;
122
+ case "boolean":
123
+ return `<span class="px-2 py-1 rounded ${
124
+ value ? "bg-green-500/20 text-green-400" : "bg-red-500/20 text-red-400"
125
+ }">${value}</span>`;
126
+ default:
127
+ return `<span class="text-sm ${
128
+ typeof value === "string" ? "font-mono" : ""
129
+ }">${String(value)}</span>`;
130
+ }
131
+ }
132
+
133
+ function toggleDropdown(button) {
134
+ const dropdown = button.nextElementSibling;
135
+ const allDropdowns = document.querySelectorAll(
136
+ ".relative.inline-block .absolute"
137
+ );
138
+
139
+ // Close all other dropdowns
140
+ allDropdowns.forEach((d) => {
141
+ if (d !== dropdown) d.classList.add("hidden");
142
+ });
143
+
144
+ // Toggle current dropdown
145
+ dropdown.classList.toggle("hidden");
146
+
147
+ // Close dropdown when clicking outside
148
+ const closeDropdown = (e) => {
149
+ if (!button.contains(e.target) && !dropdown.contains(e.target)) {
150
+ dropdown.classList.add("hidden");
151
+ document.removeEventListener("click", closeDropdown);
152
+ }
153
+ };
154
+
155
+ document.addEventListener("click", closeDropdown);
156
+ }
157
+
158
+ // Define pagination variables
159
+ let currentPage = 1;
160
+ const rowsPerPage = 10; // Number of rows per page
161
+
162
+ function renderTable() {
163
+ // Initialize records if not already done
164
+ initializeRecords();
165
+
166
+ const thead = document.getElementById("tableHead");
167
+ // Use the global records array instead of re-parsing
168
+ const records = allRecords;
169
+ console.log(records);
170
+ if (records.length > 0) {
171
+ const firstRecord = records[0];
172
+ const headers = Object.entries(firstRecord).map(([key, value]) => ({
173
+ key,
174
+ type: getDataType(value),
175
+ }));
176
+ // Render table headers
177
+ thead.innerHTML = `
178
+ <tr>
179
+ ${headers
180
+ .map(
181
+ (field) => `
182
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider">
183
+ ${field.key} (${field.type})
184
+ </th>
185
+ `
186
+ )
187
+ .join("")}
188
+ </tr>
189
+ `;
190
+
191
+ // Calculate start and end indices for the current page
192
+ const startIndex = (currentPage - 1) * rowsPerPage;
193
+ const endIndex = startIndex + rowsPerPage;
194
+
195
+ // Get the rows for the current page
196
+ const rowsForPage = records.slice(startIndex, endIndex);
197
+
198
+ // Get all row elements
199
+ const rowElements = document.querySelectorAll(".record-row");
200
+
201
+ // Render table rows
202
+ rowElements.forEach((row, index) => {
203
+ const record = rowsForPage[index];
204
+ if (record) {
205
+ row.innerHTML = headers
206
+ .map(({ key }) => {
207
+ const cellValue = record[key];
208
+ const cellType = getDataType(cellValue);
209
+
210
+ // If this is the ID cell, make it clickable
211
+ if (key === "id") {
212
+ return `
213
+ <td class="px-6 py-4">
214
+ <a href="${window.location.href.replace(
215
+ /\/$/,
216
+ ""
217
+ )}/${cellValue}"
218
+ class="text-blue-400 hover:text-blue-300 hover:underline cursor-pointer">
219
+ ${formatValue(cellValue, cellType)}
220
+ </a>
221
+ </td>
222
+ `;
223
+ } else {
224
+ return `
225
+ <td class="px-6 py-4">
226
+ ${formatValue(cellValue, cellType)}
227
+ </td>
228
+ `;
229
+ }
230
+ })
231
+ .join("");
232
+ row.style.display = ""; // Show the row
233
+
234
+ // Remove the row click event
235
+ row.style.cursor = "default";
236
+ row.onclick = null;
237
+ } else {
238
+ row.style.display = "none"; // Hide unused rows
239
+ }
240
+ });
241
+
242
+ // Render pagination controls
243
+ renderPaginationControls(records.length);
244
+ }
245
+ }
246
+
247
+ function renderPaginationControls(totalRows) {
248
+ const paginationContainer = document.getElementById("paginationControls");
249
+ const totalPages = Math.ceil(totalRows / rowsPerPage);
250
+
251
+ // Render "Previous" and "Next" buttons
252
+ paginationContainer.innerHTML = `
253
+ <button
254
+ class="px-4 py-2 bg-gray-600 text-white rounded mr-2"
255
+ onclick="changePage('prev')"
256
+ ${currentPage === 1 ? "disabled" : ""}>
257
+ Previous
258
+ </button>
259
+ <span class="text-gray-300 pt-1">Page ${currentPage} of ${totalPages}</span>
260
+ <button
261
+ class="px-4 py-2 bg-gray-600 text-white rounded ml-2"
262
+ onclick="changePage('next')"
263
+ ${currentPage === totalPages ? "disabled" : ""}>
264
+ Next
265
+ </button>
266
+ `;
267
+ }
268
+
269
+ function changePage(direction) {
270
+ const totalPages = Math.ceil(allRecords.length / rowsPerPage);
271
+
272
+ if (direction === "prev" && currentPage > 1) {
273
+ currentPage--;
274
+ } else if (direction === "next" && currentPage < totalPages) {
275
+ currentPage++;
276
+ }
277
+
278
+ renderTable();
279
+ }
280
+
281
+ function getCurrentTableIndex() {
282
+ const path = window.location.pathname;
283
+ const match = path.match(/\/admin\/(\d+)/);
284
+ return match ? parseInt(match[1]) : 0;
285
+ }
286
+
287
+ function selectTable(element, event) {
288
+ const index = element.dataset.index;
289
+
290
+ // Hide all add buttons first
291
+ document.querySelectorAll('.add-record-btn').forEach(btn => {
292
+ btn.classList.add('hidden');
293
+ });
294
+
295
+ // Show the add button for the clicked table
296
+ const addButton = element.querySelector('.add-record-btn');
297
+ if (addButton) {
298
+ addButton.classList.remove('hidden');
299
+ }
300
+
301
+ // Only update URL if it's different from current
302
+ if (index !== getCurrentTableIndex().toString()) {
303
+ window.location.href = `/admin/${index}`;
304
+ }
305
+ }
306
+
307
+ // Set active table based on URL
308
+ function setActiveTableFromUrl() {
309
+ const currentIndex = getCurrentTableIndex();
310
+ const tableItems = document.querySelectorAll(".table-item");
311
+
312
+ tableItems.forEach((item) => {
313
+ // Hide all add buttons first
314
+ const addButton = item.querySelector('.add-record-btn');
315
+ if (addButton) {
316
+ addButton.classList.add('hidden');
317
+ }
318
+
319
+ item.classList.remove("bg-blue-800");
320
+ item.classList.add("bg-gray-700");
321
+
322
+ if (parseInt(item.dataset.index) === currentIndex) {
323
+ item.classList.remove("bg-gray-700");
324
+ item.classList.add("bg-blue-800");
325
+
326
+ // Show add button for the active table
327
+ if (addButton) {
328
+ addButton.classList.remove('hidden');
329
+ }
330
+ }
331
+ });
332
+ }
333
+
334
+ // Initialize based on URL
335
+ document.addEventListener("DOMContentLoaded", () => {
336
+ initializeRecords();
337
+ renderTable();
338
+ setActiveTableFromUrl();
339
+ });
panther/panel/urls.py CHANGED
@@ -1,8 +1,13 @@
1
- from panther.panel.apis import documents_api, models_api, single_document_api, healthcheck_api
1
+ from panther.panel.views import TableView, CreateView, LoginView, DetailView, HomeView
2
2
 
3
3
  urls = {
4
- '': models_api,
5
- '<index>/': documents_api,
6
- '<index>/<document_id>/': single_document_api,
7
- 'health': healthcheck_api,
4
+ # '': models_api,
5
+ # '<index>/': documents_api,
6
+ # '<index>/<document_id>/': single_document_api,
7
+ # 'health': healthcheck_api,
8
+ '': HomeView,
9
+ '<index>/': TableView,
10
+ '<index>/create/': CreateView,
11
+ 'login/': LoginView,
12
+ '<index>/<document_id>/': DetailView,
8
13
  }