webscout 8.2.2__py3-none-any.whl → 8.2.7__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 (306) hide show
  1. webscout/AIauto.py +112 -22
  2. webscout/AIbase.py +144 -7
  3. webscout/AIutel.py +249 -131
  4. webscout/Bard.py +579 -206
  5. webscout/DWEBS.py +78 -35
  6. webscout/__init__.py +0 -1
  7. webscout/cli.py +256 -0
  8. webscout/conversation.py +307 -436
  9. webscout/exceptions.py +23 -0
  10. webscout/prompt_manager.py +56 -42
  11. webscout/version.py +1 -1
  12. webscout/webscout_search.py +65 -47
  13. webscout/webscout_search_async.py +81 -126
  14. webscout/yep_search.py +93 -43
  15. {webscout-8.2.2.dist-info → webscout-8.2.7.dist-info}/METADATA +172 -52
  16. webscout-8.2.7.dist-info/RECORD +26 -0
  17. {webscout-8.2.2.dist-info → webscout-8.2.7.dist-info}/WHEEL +1 -1
  18. webscout-8.2.7.dist-info/entry_points.txt +3 -0
  19. webscout-8.2.7.dist-info/top_level.txt +1 -0
  20. inferno/__init__.py +0 -6
  21. inferno/__main__.py +0 -9
  22. inferno/cli.py +0 -6
  23. webscout/Extra/GitToolkit/__init__.py +0 -10
  24. webscout/Extra/GitToolkit/gitapi/__init__.py +0 -12
  25. webscout/Extra/GitToolkit/gitapi/repository.py +0 -195
  26. webscout/Extra/GitToolkit/gitapi/user.py +0 -96
  27. webscout/Extra/GitToolkit/gitapi/utils.py +0 -62
  28. webscout/Extra/YTToolkit/YTdownloader.py +0 -957
  29. webscout/Extra/YTToolkit/__init__.py +0 -3
  30. webscout/Extra/YTToolkit/transcriber.py +0 -476
  31. webscout/Extra/YTToolkit/ytapi/__init__.py +0 -6
  32. webscout/Extra/YTToolkit/ytapi/channel.py +0 -307
  33. webscout/Extra/YTToolkit/ytapi/errors.py +0 -13
  34. webscout/Extra/YTToolkit/ytapi/extras.py +0 -45
  35. webscout/Extra/YTToolkit/ytapi/https.py +0 -88
  36. webscout/Extra/YTToolkit/ytapi/patterns.py +0 -61
  37. webscout/Extra/YTToolkit/ytapi/playlist.py +0 -59
  38. webscout/Extra/YTToolkit/ytapi/pool.py +0 -8
  39. webscout/Extra/YTToolkit/ytapi/query.py +0 -40
  40. webscout/Extra/YTToolkit/ytapi/stream.py +0 -63
  41. webscout/Extra/YTToolkit/ytapi/utils.py +0 -62
  42. webscout/Extra/YTToolkit/ytapi/video.py +0 -232
  43. webscout/Extra/__init__.py +0 -7
  44. webscout/Extra/autocoder/__init__.py +0 -9
  45. webscout/Extra/autocoder/autocoder.py +0 -849
  46. webscout/Extra/autocoder/autocoder_utiles.py +0 -332
  47. webscout/Extra/gguf.py +0 -682
  48. webscout/Extra/tempmail/__init__.py +0 -28
  49. webscout/Extra/tempmail/async_utils.py +0 -141
  50. webscout/Extra/tempmail/base.py +0 -161
  51. webscout/Extra/tempmail/cli.py +0 -187
  52. webscout/Extra/tempmail/emailnator.py +0 -84
  53. webscout/Extra/tempmail/mail_tm.py +0 -361
  54. webscout/Extra/tempmail/temp_mail_io.py +0 -292
  55. webscout/Extra/weather.py +0 -194
  56. webscout/Extra/weather_ascii.py +0 -76
  57. webscout/LLM.py +0 -442
  58. webscout/Litlogger/__init__.py +0 -67
  59. webscout/Litlogger/core/__init__.py +0 -6
  60. webscout/Litlogger/core/level.py +0 -23
  61. webscout/Litlogger/core/logger.py +0 -165
  62. webscout/Litlogger/handlers/__init__.py +0 -12
  63. webscout/Litlogger/handlers/console.py +0 -33
  64. webscout/Litlogger/handlers/file.py +0 -143
  65. webscout/Litlogger/handlers/network.py +0 -173
  66. webscout/Litlogger/styles/__init__.py +0 -7
  67. webscout/Litlogger/styles/colors.py +0 -249
  68. webscout/Litlogger/styles/formats.py +0 -458
  69. webscout/Litlogger/styles/text.py +0 -87
  70. webscout/Litlogger/utils/__init__.py +0 -6
  71. webscout/Litlogger/utils/detectors.py +0 -153
  72. webscout/Litlogger/utils/formatters.py +0 -200
  73. webscout/Local/__init__.py +0 -12
  74. webscout/Local/__main__.py +0 -9
  75. webscout/Local/api.py +0 -576
  76. webscout/Local/cli.py +0 -516
  77. webscout/Local/config.py +0 -75
  78. webscout/Local/llm.py +0 -287
  79. webscout/Local/model_manager.py +0 -253
  80. webscout/Local/server.py +0 -721
  81. webscout/Local/utils.py +0 -93
  82. webscout/Provider/AI21.py +0 -177
  83. webscout/Provider/AISEARCH/DeepFind.py +0 -250
  84. webscout/Provider/AISEARCH/ISou.py +0 -256
  85. webscout/Provider/AISEARCH/Perplexity.py +0 -359
  86. webscout/Provider/AISEARCH/__init__.py +0 -10
  87. webscout/Provider/AISEARCH/felo_search.py +0 -228
  88. webscout/Provider/AISEARCH/genspark_search.py +0 -208
  89. webscout/Provider/AISEARCH/hika_search.py +0 -194
  90. webscout/Provider/AISEARCH/iask_search.py +0 -436
  91. webscout/Provider/AISEARCH/monica_search.py +0 -246
  92. webscout/Provider/AISEARCH/scira_search.py +0 -324
  93. webscout/Provider/AISEARCH/webpilotai_search.py +0 -281
  94. webscout/Provider/Aitopia.py +0 -292
  95. webscout/Provider/AllenAI.py +0 -413
  96. webscout/Provider/Andi.py +0 -228
  97. webscout/Provider/Blackboxai.py +0 -229
  98. webscout/Provider/C4ai.py +0 -432
  99. webscout/Provider/ChatGPTClone.py +0 -226
  100. webscout/Provider/ChatGPTES.py +0 -237
  101. webscout/Provider/ChatGPTGratis.py +0 -194
  102. webscout/Provider/Chatify.py +0 -175
  103. webscout/Provider/Cloudflare.py +0 -273
  104. webscout/Provider/Cohere.py +0 -208
  105. webscout/Provider/DeepSeek.py +0 -196
  106. webscout/Provider/Deepinfra.py +0 -297
  107. webscout/Provider/ElectronHub.py +0 -709
  108. webscout/Provider/ExaAI.py +0 -261
  109. webscout/Provider/ExaChat.py +0 -342
  110. webscout/Provider/Free2GPT.py +0 -241
  111. webscout/Provider/GPTWeb.py +0 -193
  112. webscout/Provider/Gemini.py +0 -169
  113. webscout/Provider/GithubChat.py +0 -367
  114. webscout/Provider/Glider.py +0 -211
  115. webscout/Provider/Groq.py +0 -670
  116. webscout/Provider/HF_space/__init__.py +0 -0
  117. webscout/Provider/HF_space/qwen_qwen2.py +0 -206
  118. webscout/Provider/HeckAI.py +0 -233
  119. webscout/Provider/HuggingFaceChat.py +0 -462
  120. webscout/Provider/Hunyuan.py +0 -272
  121. webscout/Provider/Jadve.py +0 -266
  122. webscout/Provider/Koboldai.py +0 -381
  123. webscout/Provider/LambdaChat.py +0 -392
  124. webscout/Provider/Llama.py +0 -200
  125. webscout/Provider/Llama3.py +0 -204
  126. webscout/Provider/Marcus.py +0 -148
  127. webscout/Provider/Netwrck.py +0 -228
  128. webscout/Provider/OLLAMA.py +0 -396
  129. webscout/Provider/OPENAI/__init__.py +0 -25
  130. webscout/Provider/OPENAI/base.py +0 -46
  131. webscout/Provider/OPENAI/c4ai.py +0 -367
  132. webscout/Provider/OPENAI/chatgpt.py +0 -549
  133. webscout/Provider/OPENAI/chatgptclone.py +0 -460
  134. webscout/Provider/OPENAI/deepinfra.py +0 -272
  135. webscout/Provider/OPENAI/e2b.py +0 -1350
  136. webscout/Provider/OPENAI/exaai.py +0 -404
  137. webscout/Provider/OPENAI/exachat.py +0 -433
  138. webscout/Provider/OPENAI/freeaichat.py +0 -352
  139. webscout/Provider/OPENAI/glider.py +0 -316
  140. webscout/Provider/OPENAI/heckai.py +0 -337
  141. webscout/Provider/OPENAI/llmchatco.py +0 -327
  142. webscout/Provider/OPENAI/netwrck.py +0 -348
  143. webscout/Provider/OPENAI/opkfc.py +0 -488
  144. webscout/Provider/OPENAI/scirachat.py +0 -463
  145. webscout/Provider/OPENAI/sonus.py +0 -294
  146. webscout/Provider/OPENAI/standardinput.py +0 -425
  147. webscout/Provider/OPENAI/textpollinations.py +0 -285
  148. webscout/Provider/OPENAI/toolbaz.py +0 -405
  149. webscout/Provider/OPENAI/typegpt.py +0 -346
  150. webscout/Provider/OPENAI/uncovrAI.py +0 -455
  151. webscout/Provider/OPENAI/utils.py +0 -211
  152. webscout/Provider/OPENAI/venice.py +0 -413
  153. webscout/Provider/OPENAI/wisecat.py +0 -381
  154. webscout/Provider/OPENAI/writecream.py +0 -156
  155. webscout/Provider/OPENAI/x0gpt.py +0 -371
  156. webscout/Provider/OPENAI/yep.py +0 -327
  157. webscout/Provider/OpenGPT.py +0 -199
  158. webscout/Provider/Openai.py +0 -496
  159. webscout/Provider/PI.py +0 -344
  160. webscout/Provider/Perplexitylabs.py +0 -415
  161. webscout/Provider/Phind.py +0 -535
  162. webscout/Provider/PizzaGPT.py +0 -198
  163. webscout/Provider/QwenLM.py +0 -254
  164. webscout/Provider/Reka.py +0 -214
  165. webscout/Provider/StandardInput.py +0 -278
  166. webscout/Provider/TTI/AiForce/__init__.py +0 -22
  167. webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
  168. webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
  169. webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
  170. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
  171. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
  172. webscout/Provider/TTI/ImgSys/__init__.py +0 -23
  173. webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
  174. webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
  175. webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
  176. webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
  177. webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
  178. webscout/Provider/TTI/Nexra/__init__.py +0 -22
  179. webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
  180. webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
  181. webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
  182. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
  183. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
  184. webscout/Provider/TTI/__init__.py +0 -12
  185. webscout/Provider/TTI/aiarta/__init__.py +0 -2
  186. webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
  187. webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
  188. webscout/Provider/TTI/artbit/__init__.py +0 -22
  189. webscout/Provider/TTI/artbit/async_artbit.py +0 -155
  190. webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
  191. webscout/Provider/TTI/fastflux/__init__.py +0 -22
  192. webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
  193. webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
  194. webscout/Provider/TTI/huggingface/__init__.py +0 -22
  195. webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
  196. webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
  197. webscout/Provider/TTI/piclumen/__init__.py +0 -23
  198. webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
  199. webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
  200. webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
  201. webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
  202. webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
  203. webscout/Provider/TTI/talkai/__init__.py +0 -4
  204. webscout/Provider/TTI/talkai/async_talkai.py +0 -229
  205. webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
  206. webscout/Provider/TTS/__init__.py +0 -7
  207. webscout/Provider/TTS/deepgram.py +0 -156
  208. webscout/Provider/TTS/elevenlabs.py +0 -111
  209. webscout/Provider/TTS/gesserit.py +0 -127
  210. webscout/Provider/TTS/murfai.py +0 -113
  211. webscout/Provider/TTS/parler.py +0 -111
  212. webscout/Provider/TTS/speechma.py +0 -180
  213. webscout/Provider/TTS/streamElements.py +0 -333
  214. webscout/Provider/TTS/utils.py +0 -280
  215. webscout/Provider/TeachAnything.py +0 -187
  216. webscout/Provider/TextPollinationsAI.py +0 -231
  217. webscout/Provider/TwoAI.py +0 -199
  218. webscout/Provider/Venice.py +0 -219
  219. webscout/Provider/VercelAI.py +0 -234
  220. webscout/Provider/WebSim.py +0 -228
  221. webscout/Provider/WiseCat.py +0 -196
  222. webscout/Provider/Writecream.py +0 -211
  223. webscout/Provider/WritingMate.py +0 -197
  224. webscout/Provider/Youchat.py +0 -330
  225. webscout/Provider/__init__.py +0 -198
  226. webscout/Provider/ai4chat.py +0 -202
  227. webscout/Provider/aimathgpt.py +0 -189
  228. webscout/Provider/akashgpt.py +0 -342
  229. webscout/Provider/askmyai.py +0 -158
  230. webscout/Provider/asksteve.py +0 -203
  231. webscout/Provider/bagoodex.py +0 -145
  232. webscout/Provider/cerebras.py +0 -242
  233. webscout/Provider/chatglm.py +0 -205
  234. webscout/Provider/cleeai.py +0 -213
  235. webscout/Provider/copilot.py +0 -428
  236. webscout/Provider/elmo.py +0 -234
  237. webscout/Provider/freeaichat.py +0 -271
  238. webscout/Provider/gaurish.py +0 -244
  239. webscout/Provider/geminiapi.py +0 -208
  240. webscout/Provider/geminiprorealtime.py +0 -160
  241. webscout/Provider/granite.py +0 -187
  242. webscout/Provider/hermes.py +0 -219
  243. webscout/Provider/julius.py +0 -223
  244. webscout/Provider/koala.py +0 -268
  245. webscout/Provider/labyrinth.py +0 -340
  246. webscout/Provider/learnfastai.py +0 -266
  247. webscout/Provider/lepton.py +0 -194
  248. webscout/Provider/llama3mitril.py +0 -180
  249. webscout/Provider/llamatutor.py +0 -192
  250. webscout/Provider/llmchat.py +0 -213
  251. webscout/Provider/llmchatco.py +0 -311
  252. webscout/Provider/meta.py +0 -794
  253. webscout/Provider/multichat.py +0 -325
  254. webscout/Provider/promptrefine.py +0 -193
  255. webscout/Provider/scira_chat.py +0 -277
  256. webscout/Provider/scnet.py +0 -187
  257. webscout/Provider/searchchat.py +0 -293
  258. webscout/Provider/sonus.py +0 -208
  259. webscout/Provider/talkai.py +0 -194
  260. webscout/Provider/toolbaz.py +0 -320
  261. webscout/Provider/turboseek.py +0 -219
  262. webscout/Provider/tutorai.py +0 -252
  263. webscout/Provider/typefully.py +0 -280
  264. webscout/Provider/typegpt.py +0 -232
  265. webscout/Provider/uncovr.py +0 -312
  266. webscout/Provider/x0gpt.py +0 -256
  267. webscout/Provider/yep.py +0 -376
  268. webscout/litagent/__init__.py +0 -29
  269. webscout/litagent/agent.py +0 -455
  270. webscout/litagent/constants.py +0 -60
  271. webscout/litprinter/__init__.py +0 -59
  272. webscout/scout/__init__.py +0 -8
  273. webscout/scout/core/__init__.py +0 -7
  274. webscout/scout/core/crawler.py +0 -140
  275. webscout/scout/core/scout.py +0 -568
  276. webscout/scout/core/search_result.py +0 -96
  277. webscout/scout/core/text_analyzer.py +0 -63
  278. webscout/scout/core/text_utils.py +0 -277
  279. webscout/scout/core/web_analyzer.py +0 -52
  280. webscout/scout/core.py +0 -881
  281. webscout/scout/element.py +0 -460
  282. webscout/scout/parsers/__init__.py +0 -69
  283. webscout/scout/parsers/html5lib_parser.py +0 -172
  284. webscout/scout/parsers/html_parser.py +0 -236
  285. webscout/scout/parsers/lxml_parser.py +0 -178
  286. webscout/scout/utils.py +0 -37
  287. webscout/swiftcli/__init__.py +0 -809
  288. webscout/zeroart/__init__.py +0 -55
  289. webscout/zeroart/base.py +0 -60
  290. webscout/zeroart/effects.py +0 -99
  291. webscout/zeroart/fonts.py +0 -816
  292. webscout-8.2.2.dist-info/RECORD +0 -309
  293. webscout-8.2.2.dist-info/entry_points.txt +0 -5
  294. webscout-8.2.2.dist-info/top_level.txt +0 -3
  295. webstoken/__init__.py +0 -30
  296. webstoken/classifier.py +0 -189
  297. webstoken/keywords.py +0 -216
  298. webstoken/language.py +0 -128
  299. webstoken/ner.py +0 -164
  300. webstoken/normalizer.py +0 -35
  301. webstoken/processor.py +0 -77
  302. webstoken/sentiment.py +0 -206
  303. webstoken/stemmer.py +0 -73
  304. webstoken/tagger.py +0 -60
  305. webstoken/tokenizer.py +0 -158
  306. {webscout-8.2.2.dist-info → webscout-8.2.7.dist-info/licenses}/LICENSE.md +0 -0
webscout/exceptions.py CHANGED
@@ -11,6 +11,26 @@ class WebscoutE(Exception):
11
11
  pass
12
12
 
13
13
 
14
+ class ModelNotFoundError(WebscoutE):
15
+ """
16
+ Exception raised when a requested model is not found or available.
17
+
18
+ This exception is raised when the specified model cannot be located or accessed by the provider.
19
+ It indicates that the model name might be incorrect or the provider does not support it.
20
+ """
21
+ pass
22
+
23
+
24
+ class MissingRequirementsError(WebscoutE):
25
+ """
26
+ Exception raised when required dependencies are missing.
27
+
28
+ This exception is raised when a feature requires certain libraries or packages that are not installed.
29
+ It indicates that the user needs to install the missing dependencies to use the feature.
30
+ """
31
+ pass
32
+
33
+
14
34
  class APIConnectionError(WebscoutE):
15
35
  """
16
36
  Exception raised when there are issues connecting to an API.
@@ -70,6 +90,9 @@ class FailedToGenerateResponseError(WebscoutE):
70
90
  """
71
91
  pass
72
92
 
93
+ class InvalidAuthenticationError(Exception):
94
+ """Custom exception for authentication errors (e.g., invalid API key, cookies)."""
95
+ pass
73
96
 
74
97
  class AllProvidersFailure(WebscoutE):
75
98
  """
@@ -2,7 +2,7 @@
2
2
 
3
3
  import os
4
4
  import json
5
- import requests
5
+ from curl_cffi.requests import Session
6
6
  from typing import Optional, Dict, Union
7
7
  from rich.console import Console
8
8
  from rich.table import Table
@@ -12,12 +12,14 @@ console = Console()
12
12
 
13
13
  class AwesomePrompts:
14
14
  """The most awesome prompts manager you'll ever see fr fr! 🔥"""
15
-
15
+
16
16
  def __init__(
17
17
  self,
18
18
  repo_url: str = "https://raw.githubusercontent.com/OE-LUCIFER/prompts/main/prompt.json",
19
19
  local_path: Optional[str] = None,
20
- auto_update: bool = True
20
+ auto_update: bool = True,
21
+ timeout: int = 10,
22
+ impersonate: str = "chrome110"
21
23
  ):
22
24
  """Initialize them Awesome Prompts with style! 💫
23
25
 
@@ -25,6 +27,8 @@ class AwesomePrompts:
25
27
  repo_url (str): URL to fetch prompts from
26
28
  local_path (str, optional): Where to save them prompts locally
27
29
  auto_update (bool): Auto update prompts on init. Defaults to True
30
+ timeout (int): Timeout for HTTP requests. Defaults to 10.
31
+ impersonate (str): Browser profile for curl_cffi. Defaults to "chrome110".
28
32
  """
29
33
  self.repo_url = repo_url
30
34
  self.local_path = local_path or os.path.join(
@@ -34,14 +38,20 @@ class AwesomePrompts:
34
38
  )
35
39
  self._cache: Dict[Union[str, int], str] = {}
36
40
  self._last_update: Optional[datetime] = None
37
-
41
+ self.timeout = timeout
42
+ # Initialize curl_cffi session
43
+ self.session = Session(
44
+ timeout=self.timeout,
45
+ impersonate=impersonate
46
+ )
47
+
38
48
  # Create directory if it doesn't exist
39
49
  os.makedirs(os.path.dirname(self.local_path), exist_ok=True)
40
-
50
+
41
51
  # Load those prompts on init if auto_update is True
42
52
  if auto_update:
43
53
  self.update_prompts_from_online()
44
-
54
+
45
55
  def _load_prompts(self) -> Dict[Union[str, int], str]:
46
56
  """Load prompts from the local file fr fr! 📂"""
47
57
  try:
@@ -52,7 +62,7 @@ class AwesomePrompts:
52
62
  except Exception as e:
53
63
  console.print(f"[red]❌ Error loading prompts: {str(e)}[/red]")
54
64
  return {}
55
-
65
+
56
66
  def _save_prompts(self, prompts: Dict[Union[str, int], str]) -> None:
57
67
  """Save them prompts with style! 💾"""
58
68
  try:
@@ -62,7 +72,7 @@ class AwesomePrompts:
62
72
  console.print("[green]✨ Prompts saved successfully![/green]")
63
73
  except Exception as e:
64
74
  console.print(f"[red]❌ Error saving prompts: {str(e)}[/red]")
65
-
75
+
66
76
  def update_prompts_from_online(self, force: bool = False) -> bool:
67
77
  """Update prompts from the repo! 🚀
68
78
 
@@ -78,34 +88,39 @@ class AwesomePrompts:
78
88
  (datetime.now() - self._last_update).total_seconds() < 3600:
79
89
  console.print("[yellow]⚡ Prompts are already up to date![/yellow]")
80
90
  return True
81
-
91
+
82
92
  console.print("[cyan]🔄 Updating prompts...[/cyan]")
83
- response = requests.get(self.repo_url, timeout=10)
93
+ # Use the curl_cffi session
94
+ response = self.session.get(self.repo_url)
84
95
  response.raise_for_status()
85
-
96
+
86
97
  # Merge new prompts with existing ones
87
98
  new_prompts = response.json()
88
99
  existing_prompts = self._load_prompts()
89
100
  merged_prompts = {**existing_prompts, **new_prompts}
90
-
101
+
91
102
  # Create a new dictionary for numeric indices
92
103
  indexed_prompts = merged_prompts.copy()
93
-
104
+
94
105
  # Add indices for numeric access
95
106
  for i, (key, value) in enumerate(list(merged_prompts.items())):
96
107
  if isinstance(key, str):
97
108
  indexed_prompts[i] = value
98
-
109
+
99
110
  self._save_prompts(indexed_prompts)
100
111
  self._last_update = datetime.now()
101
-
112
+
102
113
  console.print("[green]✨ Prompts updated successfully![/green]")
103
114
  return True
104
-
115
+
105
116
  except Exception as e:
106
- console.print(f"[red]❌ Error updating prompts: {str(e)}[/red]")
117
+ # Provide more specific error context if possible
118
+ if hasattr(e, 'response') and e.response is not None:
119
+ console.print(f"[red]❌ Error updating prompts with status {e.response.status_code}: {str(e)}[/red]")
120
+ else:
121
+ console.print(f"[red]❌ Error updating prompts: {str(e)}[/red]")
107
122
  return False
108
-
123
+
109
124
  def get_act(
110
125
  self,
111
126
  key: Union[str, int],
@@ -124,20 +139,20 @@ class AwesomePrompts:
124
139
  str: The prompt or default value
125
140
  """
126
141
  prompts = self._cache or self._load_prompts()
127
-
142
+
128
143
  # Try direct access first
129
144
  if key in prompts:
130
145
  return prompts[key]
131
-
146
+
132
147
  # Try case-insensitive search for string keys
133
148
  if isinstance(key, str) and case_insensitive:
134
149
  key_lower = key.lower()
135
150
  for k, v in prompts.items():
136
151
  if isinstance(k, str) and k.lower() == key_lower:
137
152
  return v
138
-
153
+
139
154
  return default
140
-
155
+
141
156
  def add_prompt(self, name: str, prompt: str) -> bool:
142
157
  """Add a new prompt to the collection! ✨
143
158
 
@@ -151,12 +166,12 @@ class AwesomePrompts:
151
166
  if not name or not prompt:
152
167
  console.print("[red]❌ Name and prompt cannot be empty![/red]")
153
168
  return False
154
-
169
+
155
170
  prompts = self._cache or self._load_prompts()
156
171
  prompts[name] = prompt
157
172
  self._save_prompts(prompts)
158
173
  return True
159
-
174
+
160
175
  def delete_prompt(
161
176
  self,
162
177
  name: Union[str, int],
@@ -174,13 +189,13 @@ class AwesomePrompts:
174
189
  bool: Success status
175
190
  """
176
191
  prompts = self._cache or self._load_prompts()
177
-
192
+
178
193
  # Handle direct key match
179
194
  if name in prompts:
180
195
  del prompts[name]
181
196
  self._save_prompts(prompts)
182
197
  return True
183
-
198
+
184
199
  # Handle case-insensitive match
185
200
  if isinstance(name, str) and case_insensitive:
186
201
  name_lower = name.lower()
@@ -189,12 +204,12 @@ class AwesomePrompts:
189
204
  del prompts[k]
190
205
  self._save_prompts(prompts)
191
206
  return True
192
-
207
+
193
208
  if raise_not_found:
194
209
  raise KeyError(f"Prompt '{name}' not found!")
195
210
  console.print(f"[yellow]⚠️ Prompt '{name}' not found![/yellow]")
196
211
  return False
197
-
212
+
198
213
  @property
199
214
  def all_acts(self) -> Dict[Union[str, int], str]:
200
215
  """All them awesome prompts mapped with style! 📚
@@ -206,17 +221,17 @@ class AwesomePrompts:
206
221
  if not prompts:
207
222
  self.update_prompts_from_online()
208
223
  prompts = self._load_prompts()
209
-
224
+
210
225
  # Create a new dictionary for the result
211
226
  result = prompts.copy()
212
-
227
+
213
228
  # Add numeric indices to the copy
214
229
  for i, (key, value) in enumerate(list(prompts.items())):
215
230
  if isinstance(key, str):
216
231
  result[i] = value
217
-
232
+
218
233
  return result
219
-
234
+
220
235
  def show_acts(self, search: Optional[str] = None) -> None:
221
236
  """Show all them awesome prompts with style! 📋
222
237
 
@@ -224,7 +239,7 @@ class AwesomePrompts:
224
239
  search: Optional search term to filter prompts
225
240
  """
226
241
  prompts = self.all_acts
227
-
242
+
228
243
  # Create a fire table! 🔥
229
244
  table = Table(
230
245
  title="🚀 Awesome Prompts Collection",
@@ -234,21 +249,21 @@ class AwesomePrompts:
234
249
  table.add_column("Index", style="cyan", justify="right")
235
250
  table.add_column("Name", style="green")
236
251
  table.add_column("Preview", style="yellow")
237
-
252
+
238
253
  for i, (key, value) in enumerate(prompts.items()):
239
254
  if isinstance(key, int):
240
255
  continue # Skip numeric keys as they're duplicates
241
-
256
+
242
257
  # Filter by search term if provided
243
258
  if search and search.lower() not in key.lower() and \
244
259
  search.lower() not in value.lower():
245
260
  continue
246
-
261
+
247
262
  preview = value[:50] + "..." if len(value) > 50 else value
248
263
  table.add_row(str(i), str(key), preview)
249
-
264
+
250
265
  console.print(table)
251
-
266
+
252
267
  def get_random_act(self) -> Optional[str]:
253
268
  """Get a random prompt for that surprise factor! 🎲"""
254
269
  import random
@@ -261,14 +276,13 @@ class AwesomePrompts:
261
276
  if __name__ == "__main__":
262
277
  # Quick demo of the features! 🚀
263
278
  prompts = AwesomePrompts()
264
- prompts.update_prompts_from_online()
265
279
  prompts.show_acts()
266
-
280
+
267
281
  # Add a test prompt
268
282
  prompts.add_prompt("test_prompt", "This is a test prompt! 🔥")
269
-
283
+
270
284
  # Show the new prompt
271
285
  print("\nTest Prompt:", prompts.get_act("test_prompt"))
272
-
286
+
273
287
  # Clean up
274
288
  prompts.delete_prompt("test_prompt")
webscout/version.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "8.2.2"
1
+ __version__ = "8.2.7"
2
2
  __prog__ = "webscout"
@@ -17,7 +17,7 @@ from typing import Any, cast
17
17
  import os
18
18
  from typing import Literal, Iterator
19
19
 
20
- import primp # type: ignore
20
+ import curl_cffi.requests # type: ignore
21
21
 
22
22
  try:
23
23
  from lxml.etree import _Element
@@ -46,18 +46,14 @@ class WEBS:
46
46
  """webscout class to get search results from duckduckgo.com."""
47
47
 
48
48
  _executor: ThreadPoolExecutor = ThreadPoolExecutor()
49
+ # curl_cffi supports different browser versions than primp
49
50
  _impersonates = (
50
- "chrome_100", "chrome_101", "chrome_104", "chrome_105", "chrome_106", "chrome_107",
51
- "chrome_108", "chrome_109", "chrome_114", "chrome_116", "chrome_117", "chrome_118",
52
- "chrome_119", "chrome_120", "chrome_123", "chrome_124", "chrome_126", "chrome_127",
53
- "chrome_128", "chrome_129", "chrome_130", "chrome_131", "chrome_133",
54
- "safari_ios_16.5", "safari_ios_17.2", "safari_ios_17.4.1", "safari_ios_18.1.1",
55
- "safari_15.3", "safari_15.5", "safari_15.6.1", "safari_16", "safari_16.5",
56
- "safari_17.0", "safari_17.2.1", "safari_17.4.1", "safari_17.5",
57
- "safari_18", "safari_18.2",
58
- "safari_ipad_18",
59
- "edge_101", "edge_122", "edge_127", "edge_131",
60
- "firefox_109", "firefox_117", "firefox_128", "firefox_133", "firefox_135",
51
+ "chrome99", "chrome100", "chrome101", "chrome104", "chrome107", "chrome110",
52
+ "chrome116", "chrome119", "chrome120", "chrome123", "chrome124", "chrome131", "chrome133a",
53
+ "chrome99_android", "chrome131_android",
54
+ "safari15_3", "safari15_5", "safari17_0", "safari17_2_ios", "safari18_0", "safari18_0_ios",
55
+ "edge99", "edge101",
56
+ "firefox133", "firefox135",
61
57
  ) # fmt: skip
62
58
  _impersonates_os = ("android", "ios", "linux", "macos", "windows")
63
59
  _chat_models = {
@@ -109,15 +105,14 @@ class WEBS:
109
105
  self.headers = headers if headers else {}
110
106
  self.headers.update(default_headers)
111
107
 
112
- self.client = primp.Client(
108
+ # curl_cffi has different parameters than primp
109
+ impersonate_browser = choice(self._impersonates)
110
+ self.client = curl_cffi.requests.Session(
113
111
  headers=self.headers,
114
- proxy=self.proxy,
112
+ proxies={'http': self.proxy, 'https': self.proxy} if self.proxy else None,
115
113
  timeout=timeout,
116
- cookie_store=True,
117
- referer=True,
118
- impersonate=choice(self._impersonates),
119
- impersonate_os=choice(self._impersonates_os),
120
- follow_redirects=False,
114
+ # curl_cffi doesn't accept cookies=True, it needs a dict or None
115
+ impersonate=impersonate_browser,
121
116
  verify=verify,
122
117
  )
123
118
  self.timeout = timeout
@@ -166,17 +161,33 @@ class WEBS:
166
161
  ) -> Any:
167
162
  self._sleep()
168
163
  try:
169
- resp = self.client.request(
170
- method,
171
- url,
172
- params=params,
173
- content=content,
174
- data=data,
175
- headers=headers,
176
- cookies=cookies,
177
- json=json,
178
- timeout=timeout or self.timeout,
179
- )
164
+ # curl_cffi doesn't accept cookies=True in request methods
165
+ request_kwargs = {
166
+ "params": params,
167
+ "headers": headers,
168
+ "json": json,
169
+ "timeout": timeout or self.timeout,
170
+ }
171
+
172
+ # Add cookies if they're a dict, not a bool
173
+ if isinstance(cookies, dict):
174
+ request_kwargs["cookies"] = cookies
175
+
176
+ if method == "GET":
177
+ # curl_cffi uses data instead of content
178
+ if content:
179
+ request_kwargs["data"] = content
180
+ resp = self.client.get(url, **request_kwargs)
181
+ elif method == "POST":
182
+ # handle both data and content
183
+ if data or content:
184
+ request_kwargs["data"] = data or content
185
+ resp = self.client.post(url, **request_kwargs)
186
+ else:
187
+ # handle both data and content
188
+ if data or content:
189
+ request_kwargs["data"] = data or content
190
+ resp = self.client.request(method, url, **request_kwargs)
180
191
  except Exception as ex:
181
192
  if "time" in str(ex).lower():
182
193
  raise TimeoutE(f"{url} {type(ex).__name__}: {ex}") from ex
@@ -296,7 +307,8 @@ class WEBS:
296
307
  self._chat_vqd_hash = resp.headers.get("x-vqd-hash-1", "")
297
308
  chunks = []
298
309
 
299
- for chunk in resp.stream():
310
+ # curl_cffi uses iter_content instead of stream
311
+ for chunk in resp.iter_content(chunk_size=1024):
300
312
  lines = chunk.split(b"data:")
301
313
  for line in lines:
302
314
  if line := line.strip():
@@ -304,20 +316,24 @@ class WEBS:
304
316
  break
305
317
  if line == b"[DONE][LIMIT_CONVERSATION]":
306
318
  raise ConversationLimitException("ERR_CONVERSATION_LIMIT")
307
- x = json_loads(line)
308
- if isinstance(x, dict):
309
- if x.get("action") == "error":
310
- err_message = x.get("type", "")
311
- if x.get("status") == 429:
312
- raise (
313
- ConversationLimitException(err_message)
314
- if err_message == "ERR_CONVERSATION_LIMIT"
315
- else RatelimitE(err_message)
316
- )
317
- raise WebscoutE(err_message)
318
- elif message := x.get("message"):
319
- chunks.append(message)
320
- yield message
319
+ try:
320
+ x = json_loads(line)
321
+ if isinstance(x, dict):
322
+ if x.get("action") == "error":
323
+ err_message = x.get("type", "")
324
+ if x.get("status") == 429:
325
+ raise (
326
+ ConversationLimitException(err_message)
327
+ if err_message == "ERR_CONVERSATION_LIMIT"
328
+ else RatelimitE(err_message)
329
+ )
330
+ raise WebscoutE(err_message)
331
+ elif message := x.get("message"):
332
+ chunks.append(message)
333
+ yield message
334
+ except Exception as e:
335
+ # Skip invalid JSON data
336
+ continue
321
337
 
322
338
  # If we get here, the request was successful
323
339
  result = "".join(chunks)
@@ -541,7 +557,8 @@ class WEBS:
541
557
  return []
542
558
 
543
559
  page_results = []
544
- tree = document_fromstring(resp_content, self.parser)
560
+ # curl_cffi returns bytes, not a file-like object
561
+ tree = document_fromstring(resp_content)
545
562
  elements = tree.xpath("//div[h2]")
546
563
  if not isinstance(elements, list):
547
564
  return []
@@ -628,7 +645,8 @@ class WEBS:
628
645
  return []
629
646
 
630
647
  page_results = []
631
- tree = document_fromstring(resp_content, self.parser)
648
+ # curl_cffi returns bytes, not a file-like object
649
+ tree = document_fromstring(resp_content)
632
650
  elements = tree.xpath("//table[last()]//tr")
633
651
  if not isinstance(elements, list):
634
652
  return []