webscout 8.3__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.

Files changed (120) hide show
  1. webscout/AIauto.py +4 -4
  2. webscout/AIbase.py +61 -1
  3. webscout/AIutel.py +46 -53
  4. webscout/Bing_search.py +418 -0
  5. webscout/Extra/YTToolkit/ytapi/patterns.py +45 -45
  6. webscout/Extra/YTToolkit/ytapi/stream.py +1 -1
  7. webscout/Extra/YTToolkit/ytapi/video.py +10 -10
  8. webscout/Extra/autocoder/autocoder_utiles.py +1 -1
  9. webscout/Extra/gguf.py +706 -177
  10. webscout/Litlogger/formats.py +9 -0
  11. webscout/Litlogger/handlers.py +18 -0
  12. webscout/Litlogger/logger.py +43 -1
  13. webscout/Provider/AISEARCH/genspark_search.py +7 -7
  14. webscout/Provider/AISEARCH/scira_search.py +3 -2
  15. webscout/Provider/GeminiProxy.py +140 -0
  16. webscout/Provider/LambdaChat.py +7 -1
  17. webscout/Provider/MCPCore.py +78 -75
  18. webscout/Provider/OPENAI/BLACKBOXAI.py +1046 -1017
  19. webscout/Provider/OPENAI/GeminiProxy.py +328 -0
  20. webscout/Provider/OPENAI/Qwen3.py +303 -303
  21. webscout/Provider/OPENAI/README.md +5 -0
  22. webscout/Provider/OPENAI/README_AUTOPROXY.md +238 -0
  23. webscout/Provider/OPENAI/TogetherAI.py +355 -0
  24. webscout/Provider/OPENAI/__init__.py +16 -1
  25. webscout/Provider/OPENAI/autoproxy.py +332 -0
  26. webscout/Provider/OPENAI/base.py +101 -14
  27. webscout/Provider/OPENAI/chatgpt.py +15 -2
  28. webscout/Provider/OPENAI/chatgptclone.py +14 -3
  29. webscout/Provider/OPENAI/deepinfra.py +339 -328
  30. webscout/Provider/OPENAI/e2b.py +295 -74
  31. webscout/Provider/OPENAI/mcpcore.py +109 -70
  32. webscout/Provider/OPENAI/opkfc.py +18 -6
  33. webscout/Provider/OPENAI/scirachat.py +59 -50
  34. webscout/Provider/OPENAI/toolbaz.py +2 -10
  35. webscout/Provider/OPENAI/writecream.py +166 -166
  36. webscout/Provider/OPENAI/x0gpt.py +367 -367
  37. webscout/Provider/OPENAI/xenai.py +514 -0
  38. webscout/Provider/OPENAI/yep.py +389 -383
  39. webscout/Provider/STT/__init__.py +3 -0
  40. webscout/Provider/STT/base.py +281 -0
  41. webscout/Provider/STT/elevenlabs.py +265 -0
  42. webscout/Provider/TTI/__init__.py +4 -1
  43. webscout/Provider/TTI/aiarta.py +399 -365
  44. webscout/Provider/TTI/base.py +74 -2
  45. webscout/Provider/TTI/bing.py +231 -0
  46. webscout/Provider/TTI/fastflux.py +63 -30
  47. webscout/Provider/TTI/gpt1image.py +149 -0
  48. webscout/Provider/TTI/imagen.py +196 -0
  49. webscout/Provider/TTI/magicstudio.py +60 -29
  50. webscout/Provider/TTI/piclumen.py +43 -32
  51. webscout/Provider/TTI/pixelmuse.py +232 -225
  52. webscout/Provider/TTI/pollinations.py +43 -32
  53. webscout/Provider/TTI/together.py +287 -0
  54. webscout/Provider/TTI/utils.py +2 -1
  55. webscout/Provider/TTS/README.md +1 -0
  56. webscout/Provider/TTS/__init__.py +2 -1
  57. webscout/Provider/TTS/freetts.py +140 -0
  58. webscout/Provider/TTS/speechma.py +45 -39
  59. webscout/Provider/TogetherAI.py +366 -0
  60. webscout/Provider/UNFINISHED/ChutesAI.py +314 -0
  61. webscout/Provider/UNFINISHED/fetch_together_models.py +95 -0
  62. webscout/Provider/XenAI.py +324 -0
  63. webscout/Provider/__init__.py +8 -0
  64. webscout/Provider/deepseek_assistant.py +378 -0
  65. webscout/Provider/scira_chat.py +3 -2
  66. webscout/Provider/toolbaz.py +0 -1
  67. webscout/auth/__init__.py +44 -0
  68. webscout/auth/api_key_manager.py +189 -0
  69. webscout/auth/auth_system.py +100 -0
  70. webscout/auth/config.py +76 -0
  71. webscout/auth/database.py +400 -0
  72. webscout/auth/exceptions.py +67 -0
  73. webscout/auth/middleware.py +248 -0
  74. webscout/auth/models.py +130 -0
  75. webscout/auth/providers.py +257 -0
  76. webscout/auth/rate_limiter.py +254 -0
  77. webscout/auth/request_models.py +127 -0
  78. webscout/auth/request_processing.py +226 -0
  79. webscout/auth/routes.py +526 -0
  80. webscout/auth/schemas.py +103 -0
  81. webscout/auth/server.py +312 -0
  82. webscout/auth/static/favicon.svg +11 -0
  83. webscout/auth/swagger_ui.py +203 -0
  84. webscout/auth/templates/components/authentication.html +237 -0
  85. webscout/auth/templates/components/base.html +103 -0
  86. webscout/auth/templates/components/endpoints.html +750 -0
  87. webscout/auth/templates/components/examples.html +491 -0
  88. webscout/auth/templates/components/footer.html +75 -0
  89. webscout/auth/templates/components/header.html +27 -0
  90. webscout/auth/templates/components/models.html +286 -0
  91. webscout/auth/templates/components/navigation.html +70 -0
  92. webscout/auth/templates/static/api.js +455 -0
  93. webscout/auth/templates/static/icons.js +168 -0
  94. webscout/auth/templates/static/main.js +784 -0
  95. webscout/auth/templates/static/particles.js +201 -0
  96. webscout/auth/templates/static/styles.css +3353 -0
  97. webscout/auth/templates/static/ui.js +374 -0
  98. webscout/auth/templates/swagger_ui.html +170 -0
  99. webscout/client.py +49 -3
  100. webscout/litagent/Readme.md +12 -3
  101. webscout/litagent/agent.py +99 -62
  102. webscout/scout/core/scout.py +104 -26
  103. webscout/scout/element.py +139 -18
  104. webscout/swiftcli/core/cli.py +14 -3
  105. webscout/swiftcli/decorators/output.py +59 -9
  106. webscout/update_checker.py +31 -49
  107. webscout/version.py +1 -1
  108. webscout/webscout_search.py +4 -12
  109. webscout/webscout_search_async.py +3 -10
  110. webscout/yep_search.py +2 -11
  111. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/METADATA +41 -11
  112. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/RECORD +116 -68
  113. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/entry_points.txt +1 -1
  114. webscout/Provider/HF_space/__init__.py +0 -0
  115. webscout/Provider/HF_space/qwen_qwen2.py +0 -206
  116. webscout/Provider/OPENAI/api.py +0 -1035
  117. webscout/Provider/TTI/artbit.py +0 -0
  118. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/WHEEL +0 -0
  119. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/licenses/LICENSE.md +0 -0
  120. {webscout-8.3.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
- from webscout.Provider.OPENAI.api import start_server, run_api
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(port: int = 8000, api_key: str = None, default_provider: str = None, base_url: str = None):
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(host: str = '0.0.0.0', port: int = None, api_key: str = None, default_provider: str = None, base_url: str = None, debug: bool = False, show_available_providers: bool = True):
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
@@ -75,6 +75,14 @@ agent.refresh() # Generates new set of agents
75
75
  agent.auto_refresh(interval_minutes=30) # Auto-refresh every 30 minutes
76
76
  ```
77
77
 
78
+ ### IP Rotation
79
+
80
+ ```python
81
+ # Rotate the IP address used in fingerprints
82
+ ip = agent.rotate_ip()
83
+ print(ip) # 192.168.1.10 (example)
84
+ ```
85
+
78
86
  ## 💫 Real-World Examples
79
87
 
80
88
  ### With Requests
@@ -202,7 +210,7 @@ def browse_with_playwright():
202
210
  # Use these headers for all requests in this session
203
211
  ```
204
212
 
205
- 4. **New - Browser Fingerprinting Defense**:
213
+ 4. **New - Browser Fingerprinting & IP Rotation**:
206
214
  ```python
207
215
  # Create consistent browser fingerprinting
208
216
  fingerprint = agent.generate_fingerprint(browser="chrome")
@@ -212,10 +220,11 @@ def browse_with_playwright():
212
220
  'Accept-Language': fingerprint['accept_language'],
213
221
  'Accept': fingerprint['accept'],
214
222
  'Sec-Ch-Ua': fingerprint['sec_ch_ua'],
215
- 'Sec-Ch-Ua-Platform': fingerprint['platform']
223
+ 'Sec-Ch-Ua-Platform': fingerprint['platform'],
224
+ 'X-Forwarded-For': fingerprint['x-forwarded-for']
216
225
  }
217
226
 
218
- # Use this consistent set for all session requests
227
+ # Use this consistent set for all session requests while rotating IPs
219
228
  ```
220
229
 
221
230
  5. **New - Multi-threading Support**: