webscout 8.3.1__py3-none-any.whl → 8.3.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.
Potentially problematic release.
This version of webscout might be problematic. Click here for more details.
- webscout/AIutel.py +46 -53
- webscout/Bing_search.py +418 -0
- webscout/Extra/gguf.py +706 -177
- webscout/Provider/AISEARCH/genspark_search.py +7 -7
- webscout/Provider/GeminiProxy.py +140 -0
- webscout/Provider/MCPCore.py +78 -75
- webscout/Provider/OPENAI/BLACKBOXAI.py +1 -4
- webscout/Provider/OPENAI/GeminiProxy.py +328 -0
- webscout/Provider/OPENAI/README.md +2 -0
- webscout/Provider/OPENAI/README_AUTOPROXY.md +238 -0
- webscout/Provider/OPENAI/__init__.py +15 -1
- webscout/Provider/OPENAI/autoproxy.py +332 -39
- webscout/Provider/OPENAI/base.py +15 -5
- webscout/Provider/OPENAI/e2b.py +0 -1
- webscout/Provider/OPENAI/mcpcore.py +109 -70
- webscout/Provider/OPENAI/scirachat.py +59 -51
- webscout/Provider/OPENAI/toolbaz.py +2 -9
- webscout/Provider/OPENAI/xenai.py +514 -0
- webscout/Provider/OPENAI/yep.py +8 -2
- webscout/Provider/TTI/__init__.py +1 -0
- webscout/Provider/TTI/bing.py +231 -0
- webscout/Provider/TTS/speechma.py +45 -39
- webscout/Provider/TogetherAI.py +366 -0
- webscout/Provider/XenAI.py +324 -0
- webscout/Provider/__init__.py +8 -3
- webscout/Provider/deepseek_assistant.py +378 -0
- webscout/auth/__init__.py +44 -0
- webscout/auth/api_key_manager.py +189 -0
- webscout/auth/auth_system.py +100 -0
- webscout/auth/config.py +76 -0
- webscout/auth/database.py +400 -0
- webscout/auth/exceptions.py +67 -0
- webscout/auth/middleware.py +248 -0
- webscout/auth/models.py +130 -0
- webscout/auth/providers.py +257 -0
- webscout/auth/rate_limiter.py +254 -0
- webscout/auth/request_models.py +127 -0
- webscout/auth/request_processing.py +226 -0
- webscout/auth/routes.py +526 -0
- webscout/auth/schemas.py +103 -0
- webscout/auth/server.py +312 -0
- webscout/auth/static/favicon.svg +11 -0
- webscout/auth/swagger_ui.py +203 -0
- webscout/auth/templates/components/authentication.html +237 -0
- webscout/auth/templates/components/base.html +103 -0
- webscout/auth/templates/components/endpoints.html +750 -0
- webscout/auth/templates/components/examples.html +491 -0
- webscout/auth/templates/components/footer.html +75 -0
- webscout/auth/templates/components/header.html +27 -0
- webscout/auth/templates/components/models.html +286 -0
- webscout/auth/templates/components/navigation.html +70 -0
- webscout/auth/templates/static/api.js +455 -0
- webscout/auth/templates/static/icons.js +168 -0
- webscout/auth/templates/static/main.js +784 -0
- webscout/auth/templates/static/particles.js +201 -0
- webscout/auth/templates/static/styles.css +3353 -0
- webscout/auth/templates/static/ui.js +374 -0
- webscout/auth/templates/swagger_ui.html +170 -0
- webscout/client.py +49 -3
- webscout/scout/core/scout.py +104 -26
- webscout/scout/element.py +139 -18
- webscout/swiftcli/core/cli.py +14 -3
- webscout/swiftcli/decorators/output.py +59 -9
- webscout/update_checker.py +31 -49
- webscout/version.py +1 -1
- webscout/webscout_search.py +4 -12
- webscout/webscout_search_async.py +3 -10
- webscout/yep_search.py +2 -11
- {webscout-8.3.1.dist-info → webscout-8.3.2.dist-info}/METADATA +41 -11
- {webscout-8.3.1.dist-info → webscout-8.3.2.dist-info}/RECORD +74 -36
- {webscout-8.3.1.dist-info → webscout-8.3.2.dist-info}/entry_points.txt +1 -1
- webscout/Provider/HF_space/__init__.py +0 -0
- webscout/Provider/HF_space/qwen_qwen2.py +0 -206
- webscout/Provider/OPENAI/api.py +0 -1320
- {webscout-8.3.1.dist-info → webscout-8.3.2.dist-info}/WHEEL +0 -0
- {webscout-8.3.1.dist-info → webscout-8.3.2.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.3.1.dist-info → webscout-8.3.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebScout API Documentation - UI Utilities
|
|
3
|
+
* Handles UI interactions, animations, and helper functions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// UI utility functions
|
|
7
|
+
window.WebScoutUI = {
|
|
8
|
+
// Show loading state on button
|
|
9
|
+
showLoading(button, loadingText = 'Loading...') {
|
|
10
|
+
if (!button) return '';
|
|
11
|
+
|
|
12
|
+
const originalText = button.innerHTML;
|
|
13
|
+
button.disabled = true;
|
|
14
|
+
button.innerHTML = `
|
|
15
|
+
<div class="loading">
|
|
16
|
+
<div class="spinner"></div>
|
|
17
|
+
<span>${loadingText}</span>
|
|
18
|
+
</div>
|
|
19
|
+
`;
|
|
20
|
+
return originalText;
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
// Hide loading state on button
|
|
24
|
+
hideLoading(button, originalText) {
|
|
25
|
+
if (!button || !originalText) return;
|
|
26
|
+
|
|
27
|
+
button.disabled = false;
|
|
28
|
+
button.innerHTML = originalText;
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
// Display API response
|
|
32
|
+
displayResponse(containerId, response) {
|
|
33
|
+
const container = document.getElementById(containerId);
|
|
34
|
+
if (!container) return;
|
|
35
|
+
|
|
36
|
+
container.innerHTML = '';
|
|
37
|
+
container.classList.add('show');
|
|
38
|
+
|
|
39
|
+
// Create response header
|
|
40
|
+
const header = document.createElement('div');
|
|
41
|
+
header.className = 'response-header';
|
|
42
|
+
|
|
43
|
+
const statusClass = this.getStatusClass(response.status);
|
|
44
|
+
header.innerHTML = `
|
|
45
|
+
<div class="response-status">
|
|
46
|
+
<span class="status-code ${statusClass}">${response.status}</span>
|
|
47
|
+
<span class="status-text">${response.statusText}</span>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="response-time">${response.responseTime}ms</div>
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
container.appendChild(header);
|
|
53
|
+
|
|
54
|
+
// Create response body
|
|
55
|
+
const body = document.createElement('div');
|
|
56
|
+
body.className = 'response-body';
|
|
57
|
+
|
|
58
|
+
const pre = document.createElement('pre');
|
|
59
|
+
pre.innerHTML = this.formatResponseData(response.data);
|
|
60
|
+
body.appendChild(pre);
|
|
61
|
+
|
|
62
|
+
container.appendChild(body);
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
// Display image generation response
|
|
66
|
+
displayImageResponse(containerId, response) {
|
|
67
|
+
const container = document.getElementById(containerId);
|
|
68
|
+
if (!container) return;
|
|
69
|
+
|
|
70
|
+
container.innerHTML = '';
|
|
71
|
+
container.classList.add('show');
|
|
72
|
+
|
|
73
|
+
// Create response header
|
|
74
|
+
const header = document.createElement('div');
|
|
75
|
+
header.className = 'response-header';
|
|
76
|
+
|
|
77
|
+
const statusClass = this.getStatusClass(response.status);
|
|
78
|
+
header.innerHTML = `
|
|
79
|
+
<div class="response-status">
|
|
80
|
+
<span class="status-code ${statusClass}">${response.status}</span>
|
|
81
|
+
<span class="status-text">${response.statusText}</span>
|
|
82
|
+
</div>
|
|
83
|
+
<div class="response-time">${response.responseTime}ms</div>
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
container.appendChild(header);
|
|
87
|
+
|
|
88
|
+
// Create response body
|
|
89
|
+
const body = document.createElement('div');
|
|
90
|
+
body.className = 'response-body';
|
|
91
|
+
|
|
92
|
+
if (response.status === 200 && response.data.data) {
|
|
93
|
+
// Display images
|
|
94
|
+
const imagesContainer = document.createElement('div');
|
|
95
|
+
imagesContainer.className = 'images-container';
|
|
96
|
+
imagesContainer.style.cssText = `
|
|
97
|
+
display: grid;
|
|
98
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
99
|
+
gap: 1rem;
|
|
100
|
+
margin-bottom: 1rem;
|
|
101
|
+
`;
|
|
102
|
+
|
|
103
|
+
response.data.data.forEach((image, index) => {
|
|
104
|
+
const imageCard = document.createElement('div');
|
|
105
|
+
imageCard.className = 'image-card';
|
|
106
|
+
imageCard.style.cssText = `
|
|
107
|
+
border: 1px solid var(--border-color);
|
|
108
|
+
border-radius: var(--radius);
|
|
109
|
+
overflow: hidden;
|
|
110
|
+
background: var(--surface-color);
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
imageCard.innerHTML = `
|
|
114
|
+
<img src="${image.url}" alt="Generated image ${index + 1}"
|
|
115
|
+
style="width: 100%; height: auto; display: block;">
|
|
116
|
+
<div style="padding: 0.5rem; text-align: center;">
|
|
117
|
+
<a href="${image.url}" target="_blank"
|
|
118
|
+
style="color: var(--primary-color); text-decoration: none; font-size: 0.875rem;">
|
|
119
|
+
🔗 Open Full Size
|
|
120
|
+
</a>
|
|
121
|
+
</div>
|
|
122
|
+
`;
|
|
123
|
+
|
|
124
|
+
imagesContainer.appendChild(imageCard);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
body.appendChild(imagesContainer);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Add JSON response
|
|
131
|
+
const pre = document.createElement('pre');
|
|
132
|
+
pre.innerHTML = this.formatResponseData(response.data);
|
|
133
|
+
body.appendChild(pre);
|
|
134
|
+
|
|
135
|
+
container.appendChild(body);
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
// Get CSS class for status code
|
|
139
|
+
getStatusClass(status) {
|
|
140
|
+
if (status >= 200 && status < 300) return 'status-200';
|
|
141
|
+
if (status >= 400 && status < 500) return 'status-400';
|
|
142
|
+
if (status >= 500) return 'status-500';
|
|
143
|
+
return 'status-400';
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
// Format response data with syntax highlighting
|
|
147
|
+
formatResponseData(data) {
|
|
148
|
+
if (typeof data === 'string') {
|
|
149
|
+
try {
|
|
150
|
+
data = JSON.parse(data);
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return this.escapeHtml(data);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const jsonString = JSON.stringify(data, null, 2);
|
|
157
|
+
return this.highlightJSON(jsonString);
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
// Simple JSON syntax highlighting
|
|
161
|
+
highlightJSON(json) {
|
|
162
|
+
return json
|
|
163
|
+
.replace(/(".*?")\s*:/g, '<span class="json-key">$1</span>:')
|
|
164
|
+
.replace(/:\s*(".*?")/g, ': <span class="json-string">$1</span>')
|
|
165
|
+
.replace(/:\s*(\d+\.?\d*)/g, ': <span class="json-number">$1</span>')
|
|
166
|
+
.replace(/:\s*(true|false)/g, ': <span class="json-boolean">$1</span>')
|
|
167
|
+
.replace(/:\s*(null)/g, ': <span class="json-null">$1</span>');
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
// Escape HTML
|
|
171
|
+
escapeHtml(text) {
|
|
172
|
+
const div = document.createElement('div');
|
|
173
|
+
div.textContent = text;
|
|
174
|
+
return div.innerHTML;
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
// Search models
|
|
178
|
+
searchModels(query) {
|
|
179
|
+
const cards = document.querySelectorAll('.model-card');
|
|
180
|
+
const noResults = document.getElementById('no-models');
|
|
181
|
+
let visibleCount = 0;
|
|
182
|
+
|
|
183
|
+
cards.forEach(card => {
|
|
184
|
+
const modelName = card.dataset.modelName || '';
|
|
185
|
+
const isVisible = modelName.includes(query.toLowerCase());
|
|
186
|
+
card.style.display = isVisible ? 'block' : 'none';
|
|
187
|
+
if (isVisible) visibleCount++;
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
if (noResults) {
|
|
191
|
+
noResults.style.display = visibleCount === 0 ? 'block' : 'none';
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
// Filter models
|
|
196
|
+
filterModels(filter) {
|
|
197
|
+
const cards = document.querySelectorAll('.model-card');
|
|
198
|
+
const noResults = document.getElementById('no-models');
|
|
199
|
+
let visibleCount = 0;
|
|
200
|
+
|
|
201
|
+
cards.forEach(card => {
|
|
202
|
+
const modelType = card.dataset.modelType || '';
|
|
203
|
+
const modelName = card.dataset.modelName || '';
|
|
204
|
+
|
|
205
|
+
let isVisible = filter === 'all';
|
|
206
|
+
|
|
207
|
+
if (filter === 'chat') {
|
|
208
|
+
isVisible = modelType === 'model' || modelName.includes('gpt') || modelName.includes('claude');
|
|
209
|
+
} else if (filter === 'image') {
|
|
210
|
+
isVisible = modelName.includes('dall-e') || modelName.includes('stable');
|
|
211
|
+
} else if (filter === 'embedding') {
|
|
212
|
+
isVisible = modelName.includes('embedding') || modelName.includes('ada');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
card.style.display = isVisible ? 'block' : 'none';
|
|
216
|
+
if (isVisible) visibleCount++;
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
if (noResults) {
|
|
220
|
+
noResults.style.display = visibleCount === 0 ? 'block' : 'none';
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
// Download Postman collection
|
|
225
|
+
downloadPostmanCollection() {
|
|
226
|
+
const collection = {
|
|
227
|
+
info: {
|
|
228
|
+
name: "WebScout API",
|
|
229
|
+
description: "WebScout OpenAI-compatible API collection",
|
|
230
|
+
schema: "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
|
231
|
+
},
|
|
232
|
+
item: [
|
|
233
|
+
{
|
|
234
|
+
name: "Chat Completions",
|
|
235
|
+
request: {
|
|
236
|
+
method: "POST",
|
|
237
|
+
header: [
|
|
238
|
+
{
|
|
239
|
+
key: "Authorization",
|
|
240
|
+
value: "Bearer {{api_key}}",
|
|
241
|
+
type: "text"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
key: "Content-Type",
|
|
245
|
+
value: "application/json",
|
|
246
|
+
type: "text"
|
|
247
|
+
}
|
|
248
|
+
],
|
|
249
|
+
body: {
|
|
250
|
+
mode: "raw",
|
|
251
|
+
raw: JSON.stringify({
|
|
252
|
+
model: "gpt-3.5-turbo",
|
|
253
|
+
messages: [
|
|
254
|
+
{
|
|
255
|
+
role: "user",
|
|
256
|
+
content: "Hello, how are you?"
|
|
257
|
+
}
|
|
258
|
+
],
|
|
259
|
+
temperature: 0.7,
|
|
260
|
+
max_tokens: 150
|
|
261
|
+
}, null, 2)
|
|
262
|
+
},
|
|
263
|
+
url: {
|
|
264
|
+
raw: "{{base_url}}/v1/chat/completions",
|
|
265
|
+
host: ["{{base_url}}"],
|
|
266
|
+
path: ["v1", "chat", "completions"]
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: "List Models",
|
|
272
|
+
request: {
|
|
273
|
+
method: "GET",
|
|
274
|
+
header: [
|
|
275
|
+
{
|
|
276
|
+
key: "Authorization",
|
|
277
|
+
value: "Bearer {{api_key}}",
|
|
278
|
+
type: "text"
|
|
279
|
+
}
|
|
280
|
+
],
|
|
281
|
+
url: {
|
|
282
|
+
raw: "{{base_url}}/v1/models",
|
|
283
|
+
host: ["{{base_url}}"],
|
|
284
|
+
path: ["v1", "models"]
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: "Generate Image",
|
|
290
|
+
request: {
|
|
291
|
+
method: "POST",
|
|
292
|
+
header: [
|
|
293
|
+
{
|
|
294
|
+
key: "Authorization",
|
|
295
|
+
value: "Bearer {{api_key}}",
|
|
296
|
+
type: "text"
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
key: "Content-Type",
|
|
300
|
+
value: "application/json",
|
|
301
|
+
type: "text"
|
|
302
|
+
}
|
|
303
|
+
],
|
|
304
|
+
body: {
|
|
305
|
+
mode: "raw",
|
|
306
|
+
raw: JSON.stringify({
|
|
307
|
+
prompt: "A beautiful sunset over mountains",
|
|
308
|
+
model: "dall-e-2",
|
|
309
|
+
size: "512x512",
|
|
310
|
+
n: 1
|
|
311
|
+
}, null, 2)
|
|
312
|
+
},
|
|
313
|
+
url: {
|
|
314
|
+
raw: "{{base_url}}/v1/images/generations",
|
|
315
|
+
host: ["{{base_url}}"],
|
|
316
|
+
path: ["v1", "images", "generations"]
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
],
|
|
321
|
+
variable: [
|
|
322
|
+
{
|
|
323
|
+
key: "base_url",
|
|
324
|
+
value: window.WEBSCOUT_CONFIG?.baseUrl || "http://localhost:8000"
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
key: "api_key",
|
|
328
|
+
value: "your-api-key-here"
|
|
329
|
+
}
|
|
330
|
+
]
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const blob = new Blob([JSON.stringify(collection, null, 2)], { type: 'application/json' });
|
|
334
|
+
const url = URL.createObjectURL(blob);
|
|
335
|
+
const a = document.createElement('a');
|
|
336
|
+
a.href = url;
|
|
337
|
+
a.download = 'webscout-api.postman_collection.json';
|
|
338
|
+
document.body.appendChild(a);
|
|
339
|
+
a.click();
|
|
340
|
+
document.body.removeChild(a);
|
|
341
|
+
URL.revokeObjectURL(url);
|
|
342
|
+
|
|
343
|
+
WebScoutApp.showToast('Postman collection downloaded!', 'success');
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
// Global functions for backward compatibility
|
|
348
|
+
function showLoading(button, loadingText) {
|
|
349
|
+
return WebScoutUI.showLoading(button, loadingText);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function hideLoading(button, originalText) {
|
|
353
|
+
WebScoutUI.hideLoading(button, originalText);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function displayResponse(containerId, response) {
|
|
357
|
+
WebScoutUI.displayResponse(containerId, response);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function displayImageResponse(containerId, response) {
|
|
361
|
+
WebScoutUI.displayImageResponse(containerId, response);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function searchModels(query) {
|
|
365
|
+
WebScoutUI.searchModels(query);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function filterModels(filter) {
|
|
369
|
+
WebScoutUI.filterModels(filter);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function downloadPostmanCollection() {
|
|
373
|
+
WebScoutUI.downloadPostmanCollection();
|
|
374
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>{{ title }} - Swagger UI</title>
|
|
7
|
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
|
8
|
+
|
|
9
|
+
<!-- Google Fonts -->
|
|
10
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
11
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
12
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
13
|
+
|
|
14
|
+
<!-- Highlight.js for syntax highlighting -->
|
|
15
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
|
|
16
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
17
|
+
|
|
18
|
+
<!-- Custom Styles -->
|
|
19
|
+
<link rel="stylesheet" href="/static/styles.css">
|
|
20
|
+
|
|
21
|
+
<!-- SEO Meta Tags -->
|
|
22
|
+
<meta name="description" content="{{ description }} - Modern OpenAI API compatible interface with comprehensive documentation">
|
|
23
|
+
<meta name="keywords" content="API, OpenAI, Swagger, Documentation, REST, WebScout">
|
|
24
|
+
<meta name="author" content="WebScout">
|
|
25
|
+
|
|
26
|
+
<!-- Open Graph Meta Tags -->
|
|
27
|
+
<meta property="og:title" content="{{ title }} - Swagger UI">
|
|
28
|
+
<meta property="og:description" content="{{ description }}">
|
|
29
|
+
<meta property="og:type" content="website">
|
|
30
|
+
<meta property="og:url" content="{{ base_url }}">
|
|
31
|
+
|
|
32
|
+
<!-- Twitter Card Meta Tags -->
|
|
33
|
+
<meta name="twitter:card" content="summary_large_image">
|
|
34
|
+
<meta name="twitter:title" content="{{ title }} - Swagger UI">
|
|
35
|
+
<meta name="twitter:description" content="{{ description }}">
|
|
36
|
+
</head>
|
|
37
|
+
<body>
|
|
38
|
+
<!-- Modern Scroll Indicator -->
|
|
39
|
+
<div class="scroll-indicator">
|
|
40
|
+
<div class="scroll-progress" id="scroll-progress"></div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<!-- Loading Screen -->
|
|
44
|
+
<div id="loading-screen" class="loading-screen">
|
|
45
|
+
<div class="loading-content">
|
|
46
|
+
<div class="loading-spinner"></div>
|
|
47
|
+
<h2>Loading WebScout API Documentation</h2>
|
|
48
|
+
<p>Preparing your API experience...</p>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<!-- Main Application -->
|
|
53
|
+
<div id="app" class="app">
|
|
54
|
+
<header class="header">
|
|
55
|
+
<div class="container">
|
|
56
|
+
<div class="header-content">
|
|
57
|
+
<h1 class="header-title">
|
|
58
|
+
<span class="header-icon">🚀</span>
|
|
59
|
+
{{ title }}
|
|
60
|
+
</h1>
|
|
61
|
+
|
|
62
|
+
<p class="header-description">
|
|
63
|
+
{{ description }} - A modern, powerful, and intuitive API interface
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
<div class="header-status">
|
|
67
|
+
<span id="status-indicator" class="status-indicator">🟢</span>
|
|
68
|
+
<span>API Status: Online</span>
|
|
69
|
+
<span class="status-version">v{{ version }}</span>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</header>
|
|
74
|
+
|
|
75
|
+
<main class="main-content">
|
|
76
|
+
<div class="container">
|
|
77
|
+
<nav class="nav-tabs" role="tablist">
|
|
78
|
+
<button
|
|
79
|
+
class="nav-tab active"
|
|
80
|
+
role="tab"
|
|
81
|
+
aria-selected="true"
|
|
82
|
+
aria-controls="endpoints-panel"
|
|
83
|
+
data-tab="endpoints"
|
|
84
|
+
id="endpoints-tab"
|
|
85
|
+
>
|
|
86
|
+
<span class="nav-tab-icon">📡</span>
|
|
87
|
+
<span class="nav-tab-text">API Endpoints</span>
|
|
88
|
+
</button>
|
|
89
|
+
|
|
90
|
+
<button
|
|
91
|
+
class="nav-tab"
|
|
92
|
+
role="tab"
|
|
93
|
+
aria-selected="false"
|
|
94
|
+
aria-controls="authentication-panel"
|
|
95
|
+
data-tab="authentication"
|
|
96
|
+
id="authentication-tab"
|
|
97
|
+
>
|
|
98
|
+
<span class="nav-tab-icon">🔐</span>
|
|
99
|
+
<span class="nav-tab-text">Authentication</span>
|
|
100
|
+
</button>
|
|
101
|
+
|
|
102
|
+
<button
|
|
103
|
+
class="nav-tab"
|
|
104
|
+
role="tab"
|
|
105
|
+
aria-selected="false"
|
|
106
|
+
aria-controls="models-panel"
|
|
107
|
+
data-tab="models"
|
|
108
|
+
id="models-tab"
|
|
109
|
+
>
|
|
110
|
+
<span class="nav-tab-icon">🤖</span>
|
|
111
|
+
<span class="nav-tab-text">Models</span>
|
|
112
|
+
</button>
|
|
113
|
+
|
|
114
|
+
<button
|
|
115
|
+
class="nav-tab"
|
|
116
|
+
role="tab"
|
|
117
|
+
aria-selected="false"
|
|
118
|
+
aria-controls="examples-panel"
|
|
119
|
+
data-tab="examples"
|
|
120
|
+
id="examples-tab"
|
|
121
|
+
>
|
|
122
|
+
<span class="nav-tab-icon">💡</span>
|
|
123
|
+
<span class="nav-tab-text">Examples</span>
|
|
124
|
+
</button>
|
|
125
|
+
</nav>
|
|
126
|
+
|
|
127
|
+
<div class="tab-container">
|
|
128
|
+
{% include 'components/endpoints.html' %}
|
|
129
|
+
{% include 'components/authentication.html' %}
|
|
130
|
+
{% include 'components/models.html' %}
|
|
131
|
+
{% include 'components/examples.html' %}
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</main>
|
|
135
|
+
|
|
136
|
+
{% include 'components/footer.html' %}
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<!-- Toast Notifications -->
|
|
140
|
+
<div id="toast-container" class="toast-container"></div>
|
|
141
|
+
|
|
142
|
+
<!-- Modal Container -->
|
|
143
|
+
<div id="modal-container" class="modal-container"></div>
|
|
144
|
+
|
|
145
|
+
<!-- Scripts -->
|
|
146
|
+
<script src="/static/particles.js"></script>
|
|
147
|
+
<script src="/static/icons.js"></script>
|
|
148
|
+
<script src="/static/ui.js"></script>
|
|
149
|
+
<script src="/static/api.js"></script>
|
|
150
|
+
<script src="/static/main.js"></script>
|
|
151
|
+
|
|
152
|
+
<!-- Initialize Application -->
|
|
153
|
+
<script>
|
|
154
|
+
// Global configuration
|
|
155
|
+
window.WEBSCOUT_CONFIG = {
|
|
156
|
+
title: '{{ title }}',
|
|
157
|
+
description: '{{ description }}',
|
|
158
|
+
version: '{{ version }}',
|
|
159
|
+
baseUrl: '{{ base_url }}',
|
|
160
|
+
modelCount: {{ model_count }},
|
|
161
|
+
providerCount: {{ provider_count }}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Initialize app when DOM is loaded
|
|
165
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
166
|
+
WebScoutApp.init();
|
|
167
|
+
});
|
|
168
|
+
</script>
|
|
169
|
+
</body>
|
|
170
|
+
</html>
|
webscout/client.py
CHANGED
|
@@ -29,22 +29,52 @@ Exports:
|
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
31
|
from webscout.Provider.OPENAI import *
|
|
32
|
-
|
|
32
|
+
|
|
33
|
+
# Import server utilities from the FastAPI-compatible backend
|
|
34
|
+
try:
|
|
35
|
+
from webscout.auth.server import run_api
|
|
36
|
+
# Provide a simple alias for starting the server with default settings
|
|
37
|
+
def start_server(**kwargs):
|
|
38
|
+
"""Start the Webscout OpenAI-compatible API server (FastAPI backend)."""
|
|
39
|
+
run_api(**kwargs)
|
|
40
|
+
except ImportError:
|
|
41
|
+
# Fallback for environments where the backend is not available
|
|
42
|
+
def run_api(*args, **kwargs):
|
|
43
|
+
raise ImportError("webscout.auth.server.run_api is not available in this environment.")
|
|
44
|
+
def start_server(*args, **kwargs):
|
|
45
|
+
raise ImportError("webscout.auth.server.start_server is not available in this environment.")
|
|
33
46
|
|
|
34
47
|
# ---
|
|
35
48
|
# API Documentation
|
|
36
49
|
#
|
|
37
50
|
# start_server
|
|
38
51
|
# -------------
|
|
39
|
-
# def start_server(
|
|
52
|
+
# def start_server(
|
|
53
|
+
# port: int = 8000,
|
|
54
|
+
# host: str = "0.0.0.0",
|
|
55
|
+
# api_key: str = None,
|
|
56
|
+
# default_provider: str = None,
|
|
57
|
+
# base_url: str = None,
|
|
58
|
+
# workers: int = 1,
|
|
59
|
+
# log_level: str = 'info',
|
|
60
|
+
# debug: bool = False,
|
|
61
|
+
# no_auth: bool = False,
|
|
62
|
+
# no_rate_limit: bool = False
|
|
63
|
+
# ):
|
|
40
64
|
# """
|
|
41
65
|
# Start the OpenAI-compatible API server with optional configuration.
|
|
42
66
|
#
|
|
43
67
|
# Parameters:
|
|
44
68
|
# port (int, optional): The port to run the server on. Defaults to 8000.
|
|
69
|
+
# host (str, optional): Host address to bind the server. Defaults to '0.0.0.0'.
|
|
45
70
|
# api_key (str, optional): API key for authentication. If None, authentication is disabled.
|
|
46
71
|
# default_provider (str, optional): The default provider to use. If None, uses the package default.
|
|
47
72
|
# base_url (str, optional): Base URL prefix for the API (e.g., '/api/v1'). If None, no prefix is used.
|
|
73
|
+
# workers (int, optional): Number of worker processes. Defaults to 1.
|
|
74
|
+
# log_level (str, optional): Log level for the server ('debug', 'info', etc.). Defaults to 'info'.
|
|
75
|
+
# debug (bool, optional): Run the server in debug mode with auto-reload. Defaults to False.
|
|
76
|
+
# no_auth (bool, optional): Disable authentication (no API keys required). Defaults to False.
|
|
77
|
+
# no_rate_limit (bool, optional): Disable rate limiting (unlimited requests). Defaults to False.
|
|
48
78
|
#
|
|
49
79
|
# Returns:
|
|
50
80
|
# None
|
|
@@ -52,7 +82,19 @@ from webscout.Provider.OPENAI.api import start_server, run_api
|
|
|
52
82
|
#
|
|
53
83
|
# run_api
|
|
54
84
|
# -------
|
|
55
|
-
# def run_api(
|
|
85
|
+
# def run_api(
|
|
86
|
+
# host: str = '0.0.0.0',
|
|
87
|
+
# port: int = None,
|
|
88
|
+
# api_key: str = None,
|
|
89
|
+
# default_provider: str = None,
|
|
90
|
+
# base_url: str = None,
|
|
91
|
+
# debug: bool = False,
|
|
92
|
+
# workers: int = 1,
|
|
93
|
+
# log_level: str = 'info',
|
|
94
|
+
# show_available_providers: bool = True,
|
|
95
|
+
# no_auth: bool = False,
|
|
96
|
+
# no_rate_limit: bool = False,
|
|
97
|
+
# ) -> None:
|
|
56
98
|
# """
|
|
57
99
|
# Advanced server startup for the OpenAI-compatible API server.
|
|
58
100
|
#
|
|
@@ -63,7 +105,11 @@ from webscout.Provider.OPENAI.api import start_server, run_api
|
|
|
63
105
|
# default_provider (str, optional): The default provider to use. If None, uses the package default.
|
|
64
106
|
# base_url (str, optional): Base URL prefix for the API (e.g., '/api/v1'). If None, no prefix is used.
|
|
65
107
|
# debug (bool, optional): Run the server in debug mode with auto-reload. Defaults to False.
|
|
108
|
+
# workers (int, optional): Number of worker processes. Defaults to 1.
|
|
109
|
+
# log_level (str, optional): Log level for the server ('debug', 'info', etc.). Defaults to 'info'.
|
|
66
110
|
# show_available_providers (bool, optional): Print available providers on startup. Defaults to True.
|
|
111
|
+
# no_auth (bool, optional): Disable authentication (no API keys required). Defaults to False.
|
|
112
|
+
# no_rate_limit (bool, optional): Disable rate limiting (unlimited requests). Defaults to False.
|
|
67
113
|
#
|
|
68
114
|
# Returns:
|
|
69
115
|
# None
|