webscout 8.3.4__py3-none-any.whl → 8.3.6__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 (98) hide show
  1. webscout/AIutel.py +52 -1016
  2. webscout/Bard.py +12 -6
  3. webscout/DWEBS.py +66 -57
  4. webscout/Provider/AISEARCH/PERPLEXED_search.py +214 -0
  5. webscout/Provider/AISEARCH/__init__.py +11 -10
  6. webscout/Provider/AISEARCH/felo_search.py +7 -3
  7. webscout/Provider/AISEARCH/scira_search.py +2 -0
  8. webscout/Provider/AISEARCH/stellar_search.py +53 -8
  9. webscout/Provider/Deepinfra.py +13 -1
  10. webscout/Provider/Flowith.py +6 -1
  11. webscout/Provider/GithubChat.py +1 -0
  12. webscout/Provider/GptOss.py +207 -0
  13. webscout/Provider/Kimi.py +445 -0
  14. webscout/Provider/Netwrck.py +3 -6
  15. webscout/Provider/OPENAI/README.md +2 -1
  16. webscout/Provider/OPENAI/TogetherAI.py +12 -8
  17. webscout/Provider/OPENAI/TwoAI.py +94 -1
  18. webscout/Provider/OPENAI/__init__.py +4 -4
  19. webscout/Provider/OPENAI/copilot.py +20 -4
  20. webscout/Provider/OPENAI/deepinfra.py +12 -0
  21. webscout/Provider/OPENAI/e2b.py +60 -8
  22. webscout/Provider/OPENAI/flowith.py +4 -3
  23. webscout/Provider/OPENAI/generate_api_key.py +48 -0
  24. webscout/Provider/OPENAI/gptoss.py +288 -0
  25. webscout/Provider/OPENAI/kimi.py +469 -0
  26. webscout/Provider/OPENAI/netwrck.py +8 -12
  27. webscout/Provider/OPENAI/refact.py +274 -0
  28. webscout/Provider/OPENAI/scirachat.py +4 -0
  29. webscout/Provider/OPENAI/textpollinations.py +11 -10
  30. webscout/Provider/OPENAI/toolbaz.py +1 -0
  31. webscout/Provider/OPENAI/venice.py +1 -0
  32. webscout/Provider/Perplexitylabs.py +163 -147
  33. webscout/Provider/Qodo.py +30 -6
  34. webscout/Provider/TTI/__init__.py +1 -0
  35. webscout/Provider/TTI/bing.py +14 -2
  36. webscout/Provider/TTI/together.py +11 -9
  37. webscout/Provider/TTI/venice.py +368 -0
  38. webscout/Provider/TTS/README.md +0 -1
  39. webscout/Provider/TTS/__init__.py +0 -1
  40. webscout/Provider/TTS/base.py +479 -159
  41. webscout/Provider/TTS/deepgram.py +409 -156
  42. webscout/Provider/TTS/elevenlabs.py +425 -111
  43. webscout/Provider/TTS/freetts.py +317 -140
  44. webscout/Provider/TTS/gesserit.py +192 -128
  45. webscout/Provider/TTS/murfai.py +248 -113
  46. webscout/Provider/TTS/openai_fm.py +347 -129
  47. webscout/Provider/TTS/speechma.py +620 -586
  48. webscout/Provider/TextPollinationsAI.py +11 -10
  49. webscout/Provider/TogetherAI.py +12 -4
  50. webscout/Provider/TwoAI.py +96 -2
  51. webscout/Provider/TypliAI.py +33 -27
  52. webscout/Provider/UNFINISHED/VercelAIGateway.py +339 -0
  53. webscout/Provider/UNFINISHED/fetch_together_models.py +6 -11
  54. webscout/Provider/Venice.py +1 -0
  55. webscout/Provider/WiseCat.py +18 -20
  56. webscout/Provider/__init__.py +2 -96
  57. webscout/Provider/cerebras.py +83 -33
  58. webscout/Provider/copilot.py +42 -23
  59. webscout/Provider/scira_chat.py +4 -0
  60. webscout/Provider/toolbaz.py +6 -10
  61. webscout/Provider/typefully.py +1 -11
  62. webscout/__init__.py +3 -15
  63. webscout/auth/__init__.py +19 -4
  64. webscout/auth/api_key_manager.py +189 -189
  65. webscout/auth/auth_system.py +25 -40
  66. webscout/auth/config.py +105 -6
  67. webscout/auth/database.py +377 -22
  68. webscout/auth/models.py +185 -130
  69. webscout/auth/request_processing.py +175 -11
  70. webscout/auth/routes.py +99 -2
  71. webscout/auth/server.py +9 -2
  72. webscout/auth/simple_logger.py +236 -0
  73. webscout/conversation.py +22 -20
  74. webscout/sanitize.py +1078 -0
  75. webscout/scout/README.md +20 -23
  76. webscout/scout/core/crawler.py +125 -38
  77. webscout/scout/core/scout.py +26 -5
  78. webscout/version.py +1 -1
  79. webscout/webscout_search.py +13 -6
  80. webscout/webscout_search_async.py +10 -8
  81. webscout/yep_search.py +13 -5
  82. {webscout-8.3.4.dist-info → webscout-8.3.6.dist-info}/METADATA +10 -149
  83. {webscout-8.3.4.dist-info → webscout-8.3.6.dist-info}/RECORD +88 -87
  84. webscout/Provider/Glider.py +0 -225
  85. webscout/Provider/OPENAI/README_AUTOPROXY.md +0 -238
  86. webscout/Provider/OPENAI/c4ai.py +0 -394
  87. webscout/Provider/OPENAI/glider.py +0 -330
  88. webscout/Provider/OPENAI/typegpt.py +0 -368
  89. webscout/Provider/OPENAI/uncovrAI.py +0 -477
  90. webscout/Provider/TTS/sthir.py +0 -94
  91. webscout/Provider/WritingMate.py +0 -273
  92. webscout/Provider/typegpt.py +0 -284
  93. webscout/Provider/uncovr.py +0 -333
  94. /webscout/Provider/{samurai.py → UNFINISHED/samurai.py} +0 -0
  95. {webscout-8.3.4.dist-info → webscout-8.3.6.dist-info}/WHEEL +0 -0
  96. {webscout-8.3.4.dist-info → webscout-8.3.6.dist-info}/entry_points.txt +0 -0
  97. {webscout-8.3.4.dist-info → webscout-8.3.6.dist-info}/licenses/LICENSE.md +0 -0
  98. {webscout-8.3.4.dist-info → webscout-8.3.6.dist-info}/top_level.txt +0 -0
@@ -1,129 +1,347 @@
1
- ##################################################################################
2
- ## OpenAI.fm TTS Provider ##
3
- ##################################################################################
4
- import time
5
- import requests
6
- import pathlib
7
- import tempfile
8
- from io import BytesIO
9
- from webscout import exceptions
10
- from webscout.litagent import LitAgent
11
- from concurrent.futures import ThreadPoolExecutor, as_completed
12
- from webscout.Provider.TTS import utils
13
- from webscout.Provider.TTS.base import BaseTTSProvider
14
-
15
- class OpenAIFMTTS(BaseTTSProvider):
16
- """
17
- Text-to-speech provider using the OpenAI.fm API.
18
- """
19
- # Request headers
20
- headers = {
21
- "accept": "*/*",
22
- "accept-language": "en-US,en;q=0.9",
23
- "cache-control": "no-cache",
24
- "pragma": "no-cache",
25
- "sec-fetch-dest": "audio",
26
- "sec-fetch-mode": "no-cors",
27
- "sec-fetch-site": "same-origin",
28
- "user-agent": LitAgent().random(),
29
- "referer": "https://www.openai.fm"
30
- }
31
-
32
- # Available voices with their IDs
33
- all_voices = {
34
- # OpenAI.fm voices
35
- "Alloy": "alloy", # Neutral voice with balanced tone
36
- "Ash": "ash", # Calm and thoughtful male voice
37
- "Ballad": "ballad", # Soft and melodic voice
38
- "Coral": "coral", # Warm and inviting female voice
39
- "Echo": "echo", # Clear and precise voice
40
- "Fable": "fable", # Authoritative and narrative voice
41
- "Onyx": "onyx", # Deep and resonant male voice
42
- "Nova": "nova", # Energetic and bright female voice
43
- "Sage": "sage", # Measured and contemplative voice
44
- "Shimmer": "shimmer", # Bright and optimistic voice
45
- "Verse": "verse" # Melodic and rhythmic voice
46
- }
47
-
48
- def __init__(self, timeout: int = 20, proxies: dict = None):
49
- """Initializes the OpenAI.fm TTS client."""
50
- super().__init__()
51
- self.api_url = "https://www.openai.fm/api/generate"
52
- self.session = requests.Session()
53
- self.session.headers.update(self.headers)
54
- if proxies:
55
- self.session.proxies.update(proxies)
56
- self.timeout = timeout
57
-
58
- def tts(self, text: str, voice: str = "Coral", instructions: str = None, verbose: bool = True) -> str:
59
- """
60
- Converts text to speech using the OpenAI.fm API and saves it to a file.
61
-
62
- Args:
63
- text (str): The text to convert to speech
64
- voice (str): The voice to use for TTS (default: "Coral")
65
- instructions (str): Voice instructions/prompt (default: "A cheerful guide. Friendly, clear, and reassuring.")
66
- verbose (bool): Whether to print debug information (default: True)
67
-
68
- Returns:
69
- str: Path to the generated audio file
70
-
71
- Raises:
72
- exceptions.FailedToGenerateResponseError: If there is an error generating or saving the audio.
73
- """
74
- # Validate input parameters
75
- if not text or not isinstance(text, str):
76
- raise ValueError("Text input must be a non-empty string")
77
- if len(text) > 10000: # Add reasonable length limit
78
- raise ValueError("Text input exceeds maximum allowed length")
79
-
80
- assert (
81
- voice in self.all_voices
82
- ), f"Voice '{voice}' not one of [{', '.join(self.all_voices.keys())}]"
83
-
84
- with tempfile.NamedTemporaryFile(suffix=".mp3", dir=self.temp_dir, delete=False) as temp_file:
85
- filename = pathlib.Path(temp_file.name)
86
- voice_id = self.all_voices[voice]
87
-
88
- if instructions is None:
89
- instructions = "A cheerful guide. Friendly, clear, and reassuring."
90
-
91
- # Prepare parameters for the API request
92
- params = {
93
- "input": text,
94
- "prompt": instructions,
95
- "voice": voice_id
96
- }
97
-
98
- try:
99
- # Make the API request
100
- response = self.session.get(
101
- self.api_url,
102
- params=params,
103
- timeout=self.timeout
104
- )
105
- response.raise_for_status()
106
-
107
- # Save the audio file
108
- with open(filename, "wb") as f:
109
- f.write(response.content)
110
-
111
- if verbose:
112
- print(f"[debug] Audio saved to {filename}")
113
-
114
- return filename.as_posix()
115
-
116
- except requests.exceptions.RequestException as e:
117
- if verbose:
118
- print(f"[debug] Failed to perform the operation: {e}")
119
- raise exceptions.FailedToGenerateResponseError(
120
- f"Failed to perform the operation: {e}"
121
- )
122
- if __name__ == "__main__":
123
- # Example usage
124
- tts_provider = OpenAIFMTTS()
125
- try:
126
- audio_file = tts_provider.tts("Hello, this is a test.", instructions="A cheerful guide. Friendly, clear, and reassuring.", voice="Coral")
127
- print(f"Audio file generated: {audio_file}")
128
- except exceptions.FailedToGenerateResponseError as e:
129
- print(f"Error: {e}")
1
+ ##################################################################################
2
+ ## OpenAI.fm TTS Provider ##
3
+ ##################################################################################
4
+ import time
5
+ import requests
6
+ import pathlib
7
+ import tempfile
8
+ from io import BytesIO
9
+ from webscout import exceptions
10
+ from webscout.litagent import LitAgent
11
+ from concurrent.futures import ThreadPoolExecutor, as_completed
12
+ from webscout.Provider.TTS import utils
13
+ from webscout.Provider.TTS.base import BaseTTSProvider
14
+
15
+ class OpenAIFMTTS(BaseTTSProvider):
16
+ """
17
+ Text-to-speech provider using the OpenAI.fm API with OpenAI-compatible interface.
18
+
19
+ This provider follows the OpenAI TTS API structure with support for:
20
+ - Multiple TTS models (gpt-4o-mini-tts, tts-1, tts-1-hd)
21
+ - 11 built-in voices optimized for English
22
+ - Voice instructions for controlling speech aspects
23
+ - Multiple output formats
24
+ - Streaming support
25
+ """
26
+
27
+ # Request headers
28
+ headers = {
29
+ "accept": "*/*",
30
+ "accept-language": "en-US,en;q=0.9",
31
+ "cache-control": "no-cache",
32
+ "pragma": "no-cache",
33
+ "sec-fetch-dest": "audio",
34
+ "sec-fetch-mode": "no-cors",
35
+ "sec-fetch-site": "same-origin",
36
+ "user-agent": LitAgent().random(),
37
+ "referer": "https://www.openai.fm"
38
+ }
39
+
40
+ # Override supported models for OpenAI.fm
41
+ SUPPORTED_MODELS = [
42
+ "gpt-4o-mini-tts", # Latest intelligent realtime model
43
+ "tts-1", # Lower latency model
44
+ "tts-1-hd" # Higher quality model
45
+ ]
46
+
47
+ # OpenAI.fm supported voices (11 built-in voices)
48
+ SUPPORTED_VOICES = [
49
+ "alloy", # Neutral voice with balanced tone
50
+ "ash", # Calm and thoughtful male voice
51
+ "ballad", # Soft and melodic voice
52
+ "coral", # Warm and inviting female voice
53
+ "echo", # Clear and precise voice
54
+ "fable", # Authoritative and narrative voice
55
+ "nova", # Energetic and bright female voice
56
+ "onyx", # Deep and resonant male voice
57
+ "sage", # Measured and contemplative voice
58
+ "shimmer" # Bright and optimistic voice
59
+ ]
60
+
61
+ # Voice mapping for API compatibility
62
+ voice_mapping = {
63
+ "alloy": "alloy",
64
+ "ash": "ash",
65
+ "ballad": "ballad",
66
+ "coral": "coral",
67
+ "echo": "echo",
68
+ "fable": "fable",
69
+ "nova": "nova",
70
+ "onyx": "onyx",
71
+ "sage": "sage",
72
+ "shimmer": "shimmer"
73
+ }
74
+
75
+ def __init__(self, timeout: int = 20, proxies: dict = None):
76
+ """
77
+ Initialize the OpenAI.fm TTS client.
78
+
79
+ Args:
80
+ timeout (int): Request timeout in seconds
81
+ proxies (dict): Proxy configuration
82
+ """
83
+ super().__init__()
84
+ self.api_url = "https://www.openai.fm/api/generate"
85
+ self.session = requests.Session()
86
+ self.session.headers.update(self.headers)
87
+ if proxies:
88
+ self.session.proxies.update(proxies)
89
+ self.timeout = timeout
90
+
91
+ def tts(
92
+ self,
93
+ text: str,
94
+ model: str = "gpt-4o-mini-tts",
95
+ voice: str = "coral",
96
+ response_format: str = "mp3",
97
+ instructions: str = None,
98
+ verbose: bool = True
99
+ ) -> str:
100
+ """
101
+ Convert text to speech using OpenAI.fm API with OpenAI-compatible parameters.
102
+
103
+ Args:
104
+ text (str): The text to convert to speech (max 10,000 characters)
105
+ model (str): The TTS model to use (gpt-4o-mini-tts, tts-1, tts-1-hd)
106
+ voice (str): The voice to use for TTS (alloy, ash, ballad, coral, echo, fable, nova, onyx, sage, shimmer)
107
+ response_format (str): Audio format (mp3, opus, aac, flac, wav, pcm)
108
+ instructions (str): Voice instructions for controlling speech aspects like accent, tone, speed
109
+ verbose (bool): Whether to print debug information
110
+
111
+ Returns:
112
+ str: Path to the generated audio file
113
+
114
+ Raises:
115
+ ValueError: If input parameters are invalid
116
+ exceptions.FailedToGenerateResponseError: If there is an error generating or saving the audio
117
+ """
118
+ # Validate input parameters
119
+ if not text or not isinstance(text, str):
120
+ raise ValueError("Input text must be a non-empty string")
121
+ if len(text) > 10000:
122
+ raise ValueError("Input text exceeds maximum allowed length of 10,000 characters")
123
+
124
+ # Validate model, voice, and format using base class methods
125
+ model = self.validate_model(model)
126
+ voice = self.validate_voice(voice)
127
+ response_format = self.validate_format(response_format)
128
+
129
+ # Map voice to API format
130
+ voice_id = self.voice_mapping.get(voice, voice)
131
+
132
+ # Set default instructions if not provided
133
+ if instructions is None:
134
+ instructions = "Speak in a cheerful and positive tone."
135
+
136
+ # Create temporary file with appropriate extension
137
+ file_extension = f".{response_format}" if response_format != "pcm" else ".wav"
138
+ with tempfile.NamedTemporaryFile(suffix=file_extension, dir=self.temp_dir, delete=False) as temp_file:
139
+ filename = pathlib.Path(temp_file.name)
140
+
141
+ # Prepare parameters for the API request
142
+ params = {
143
+ "input": text,
144
+ "prompt": instructions,
145
+ "voice": voice_id,
146
+ "model": model,
147
+ "response_format": response_format
148
+ }
149
+
150
+ try:
151
+ # Make the API request
152
+ response = self.session.get(
153
+ self.api_url,
154
+ params=params,
155
+ timeout=self.timeout
156
+ )
157
+ response.raise_for_status()
158
+
159
+ # Validate response content
160
+ if not response.content:
161
+ raise exceptions.FailedToGenerateResponseError("Empty response from API")
162
+
163
+ # Save the audio file
164
+ with open(filename, "wb") as f:
165
+ f.write(response.content)
166
+
167
+ if verbose:
168
+ print(f"[debug] Speech generated successfully")
169
+ print(f"[debug] Model: {model}")
170
+ print(f"[debug] Voice: {voice}")
171
+ print(f"[debug] Format: {response_format}")
172
+ print(f"[debug] Audio saved to {filename}")
173
+
174
+ return filename.as_posix()
175
+
176
+ except requests.exceptions.RequestException as e:
177
+ if verbose:
178
+ print(f"[debug] Failed to generate speech: {e}")
179
+ raise exceptions.FailedToGenerateResponseError(
180
+ f"Failed to generate speech: {e}"
181
+ )
182
+ except Exception as e:
183
+ if verbose:
184
+ print(f"[debug] Unexpected error: {e}")
185
+ raise exceptions.FailedToGenerateResponseError(
186
+ f"Unexpected error during speech generation: {e}"
187
+ )
188
+
189
+ def create_speech(
190
+ self,
191
+ input: str,
192
+ model: str = "gpt-4o-mini-tts",
193
+ voice: str = "coral",
194
+ response_format: str = "mp3",
195
+ instructions: str = None,
196
+ verbose: bool = False
197
+ ) -> str:
198
+ """
199
+ OpenAI-compatible speech creation interface.
200
+
201
+ Args:
202
+ input (str): The text to convert to speech
203
+ model (str): The TTS model to use
204
+ voice (str): The voice to use
205
+ response_format (str): Audio format
206
+ instructions (str): Voice instructions
207
+ verbose (bool): Whether to print debug information
208
+
209
+ Returns:
210
+ str: Path to the generated audio file
211
+ """
212
+ return self.tts(
213
+ text=input,
214
+ model=model,
215
+ voice=voice,
216
+ response_format=response_format,
217
+ instructions=instructions,
218
+ verbose=verbose
219
+ )
220
+
221
+ def with_streaming_response(self):
222
+ """
223
+ Return a streaming response context manager (OpenAI-compatible).
224
+
225
+ Returns:
226
+ StreamingResponseContextManager: Context manager for streaming responses
227
+ """
228
+ return StreamingResponseContextManager(self)
229
+
230
+
231
+ class StreamingResponseContextManager:
232
+ """
233
+ Context manager for streaming TTS responses (OpenAI-compatible).
234
+ """
235
+
236
+ def __init__(self, tts_provider: OpenAIFMTTS):
237
+ self.tts_provider = tts_provider
238
+ self.audio_file = None
239
+
240
+ def create(
241
+ self,
242
+ input: str,
243
+ model: str = "gpt-4o-mini-tts",
244
+ voice: str = "coral",
245
+ response_format: str = "mp3",
246
+ instructions: str = None
247
+ ):
248
+ """
249
+ Create speech with streaming capability.
250
+
251
+ Args:
252
+ input (str): The text to convert to speech
253
+ model (str): The TTS model to use
254
+ voice (str): The voice to use
255
+ response_format (str): Audio format
256
+ instructions (str): Voice instructions
257
+
258
+ Returns:
259
+ StreamingResponse: Streaming response object
260
+ """
261
+ self.audio_file = self.tts_provider.create_speech(
262
+ input=input,
263
+ model=model,
264
+ voice=voice,
265
+ response_format=response_format,
266
+ instructions=instructions
267
+ )
268
+ return StreamingResponse(self.audio_file)
269
+
270
+ def __enter__(self):
271
+ return self
272
+
273
+ def __exit__(self, exc_type, exc_val, exc_tb):
274
+ pass
275
+
276
+
277
+ class StreamingResponse:
278
+ """
279
+ Streaming response object for TTS audio (OpenAI-compatible).
280
+ """
281
+
282
+ def __init__(self, audio_file: str):
283
+ self.audio_file = audio_file
284
+
285
+ def __enter__(self):
286
+ """Enter the context manager."""
287
+ return self
288
+
289
+ def __exit__(self, exc_type, exc_val, exc_tb):
290
+ """Exit the context manager."""
291
+ pass
292
+
293
+ def stream_to_file(self, file_path: str, chunk_size: int = 1024):
294
+ """
295
+ Stream audio content to a file.
296
+
297
+ Args:
298
+ file_path (str): Destination file path
299
+ chunk_size (int): Size of chunks to read/write
300
+ """
301
+ import shutil
302
+ shutil.copy2(self.audio_file, file_path)
303
+
304
+ def iter_bytes(self, chunk_size: int = 1024):
305
+ """
306
+ Iterate over audio bytes in chunks.
307
+
308
+ Args:
309
+ chunk_size (int): Size of chunks to yield
310
+
311
+ Yields:
312
+ bytes: Audio data chunks
313
+ """
314
+ with open(self.audio_file, 'rb') as f:
315
+ while chunk := f.read(chunk_size):
316
+ yield chunk
317
+
318
+
319
+ if __name__ == "__main__":
320
+ # Example usage demonstrating OpenAI-compatible interface
321
+ tts_provider = OpenAIFMTTS()
322
+
323
+ try:
324
+ # Basic usage
325
+ print("Testing basic speech generation...")
326
+ audio_file = tts_provider.create_speech(
327
+ input="Today is a wonderful day to build something people love!",
328
+ model="gpt-4o-mini-tts",
329
+ voice="coral",
330
+ instructions="Speak in a cheerful and positive tone."
331
+ )
332
+ print(f"Audio file generated: {audio_file}")
333
+
334
+ # Streaming usage
335
+ print("\nTesting streaming response...")
336
+ with tts_provider.with_streaming_response().create(
337
+ input="This is a streaming test.",
338
+ voice="alloy",
339
+ response_format="wav"
340
+ ) as response:
341
+ response.stream_to_file("streaming_test.wav")
342
+ print("Streaming audio saved to streaming_test.wav")
343
+
344
+ except exceptions.FailedToGenerateResponseError as e:
345
+ print(f"Error: {e}")
346
+ except Exception as e:
347
+ print(f"Unexpected error: {e}")