webscout 8.2.2__py3-none-any.whl → 2026.1.19__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (483) hide show
  1. webscout/AIauto.py +524 -143
  2. webscout/AIbase.py +247 -123
  3. webscout/AIutel.py +68 -132
  4. webscout/Bard.py +1072 -535
  5. webscout/Extra/GitToolkit/__init__.py +2 -2
  6. webscout/Extra/GitToolkit/gitapi/__init__.py +20 -12
  7. webscout/Extra/GitToolkit/gitapi/gist.py +142 -0
  8. webscout/Extra/GitToolkit/gitapi/organization.py +91 -0
  9. webscout/Extra/GitToolkit/gitapi/repository.py +308 -195
  10. webscout/Extra/GitToolkit/gitapi/search.py +162 -0
  11. webscout/Extra/GitToolkit/gitapi/trending.py +236 -0
  12. webscout/Extra/GitToolkit/gitapi/user.py +128 -96
  13. webscout/Extra/GitToolkit/gitapi/utils.py +82 -62
  14. webscout/Extra/YTToolkit/README.md +443 -0
  15. webscout/Extra/YTToolkit/YTdownloader.py +953 -957
  16. webscout/Extra/YTToolkit/__init__.py +3 -3
  17. webscout/Extra/YTToolkit/transcriber.py +595 -476
  18. webscout/Extra/YTToolkit/ytapi/README.md +230 -0
  19. webscout/Extra/YTToolkit/ytapi/__init__.py +22 -6
  20. webscout/Extra/YTToolkit/ytapi/captions.py +190 -0
  21. webscout/Extra/YTToolkit/ytapi/channel.py +302 -307
  22. webscout/Extra/YTToolkit/ytapi/errors.py +13 -13
  23. webscout/Extra/YTToolkit/ytapi/extras.py +178 -45
  24. webscout/Extra/YTToolkit/ytapi/hashtag.py +120 -0
  25. webscout/Extra/YTToolkit/ytapi/https.py +89 -88
  26. webscout/Extra/YTToolkit/ytapi/patterns.py +61 -61
  27. webscout/Extra/YTToolkit/ytapi/playlist.py +59 -59
  28. webscout/Extra/YTToolkit/ytapi/pool.py +8 -8
  29. webscout/Extra/YTToolkit/ytapi/query.py +143 -40
  30. webscout/Extra/YTToolkit/ytapi/shorts.py +122 -0
  31. webscout/Extra/YTToolkit/ytapi/stream.py +68 -63
  32. webscout/Extra/YTToolkit/ytapi/suggestions.py +97 -0
  33. webscout/Extra/YTToolkit/ytapi/utils.py +66 -62
  34. webscout/Extra/YTToolkit/ytapi/video.py +189 -18
  35. webscout/Extra/__init__.py +2 -3
  36. webscout/Extra/gguf.py +1298 -682
  37. webscout/Extra/tempmail/README.md +488 -0
  38. webscout/Extra/tempmail/__init__.py +28 -28
  39. webscout/Extra/tempmail/async_utils.py +143 -141
  40. webscout/Extra/tempmail/base.py +172 -161
  41. webscout/Extra/tempmail/cli.py +191 -187
  42. webscout/Extra/tempmail/emailnator.py +88 -84
  43. webscout/Extra/tempmail/mail_tm.py +378 -361
  44. webscout/Extra/tempmail/temp_mail_io.py +304 -292
  45. webscout/Extra/weather.py +196 -194
  46. webscout/Extra/weather_ascii.py +17 -15
  47. webscout/Provider/AISEARCH/PERPLEXED_search.py +175 -0
  48. webscout/Provider/AISEARCH/Perplexity.py +237 -304
  49. webscout/Provider/AISEARCH/README.md +106 -0
  50. webscout/Provider/AISEARCH/__init__.py +16 -10
  51. webscout/Provider/AISEARCH/brave_search.py +298 -0
  52. webscout/Provider/AISEARCH/iask_search.py +130 -209
  53. webscout/Provider/AISEARCH/monica_search.py +200 -246
  54. webscout/Provider/AISEARCH/webpilotai_search.py +242 -281
  55. webscout/Provider/Algion.py +413 -0
  56. webscout/Provider/Andi.py +74 -69
  57. webscout/Provider/Apriel.py +313 -0
  58. webscout/Provider/Ayle.py +323 -0
  59. webscout/Provider/ChatSandbox.py +329 -0
  60. webscout/Provider/ClaudeOnline.py +365 -0
  61. webscout/Provider/Cohere.py +232 -208
  62. webscout/Provider/DeepAI.py +367 -0
  63. webscout/Provider/Deepinfra.py +343 -173
  64. webscout/Provider/EssentialAI.py +217 -0
  65. webscout/Provider/ExaAI.py +274 -261
  66. webscout/Provider/Gemini.py +60 -54
  67. webscout/Provider/GithubChat.py +385 -367
  68. webscout/Provider/Gradient.py +286 -0
  69. webscout/Provider/Groq.py +556 -670
  70. webscout/Provider/HadadXYZ.py +323 -0
  71. webscout/Provider/HeckAI.py +392 -233
  72. webscout/Provider/HuggingFace.py +387 -0
  73. webscout/Provider/IBM.py +340 -0
  74. webscout/Provider/Jadve.py +317 -266
  75. webscout/Provider/K2Think.py +306 -0
  76. webscout/Provider/Koboldai.py +221 -381
  77. webscout/Provider/Netwrck.py +273 -228
  78. webscout/Provider/Nvidia.py +310 -0
  79. webscout/Provider/OPENAI/DeepAI.py +489 -0
  80. webscout/Provider/OPENAI/K2Think.py +423 -0
  81. webscout/Provider/OPENAI/PI.py +463 -0
  82. webscout/Provider/OPENAI/README.md +890 -0
  83. webscout/Provider/OPENAI/TogetherAI.py +405 -0
  84. webscout/Provider/OPENAI/TwoAI.py +255 -0
  85. webscout/Provider/OPENAI/__init__.py +148 -25
  86. webscout/Provider/OPENAI/ai4chat.py +348 -0
  87. webscout/Provider/OPENAI/akashgpt.py +436 -0
  88. webscout/Provider/OPENAI/algion.py +303 -0
  89. webscout/Provider/OPENAI/ayle.py +365 -0
  90. webscout/Provider/OPENAI/base.py +253 -46
  91. webscout/Provider/OPENAI/cerebras.py +296 -0
  92. webscout/Provider/OPENAI/chatgpt.py +514 -193
  93. webscout/Provider/OPENAI/chatsandbox.py +233 -0
  94. webscout/Provider/OPENAI/deepinfra.py +403 -272
  95. webscout/Provider/OPENAI/e2b.py +2370 -1350
  96. webscout/Provider/OPENAI/elmo.py +278 -0
  97. webscout/Provider/OPENAI/exaai.py +186 -138
  98. webscout/Provider/OPENAI/freeassist.py +446 -0
  99. webscout/Provider/OPENAI/gradient.py +448 -0
  100. webscout/Provider/OPENAI/groq.py +380 -0
  101. webscout/Provider/OPENAI/hadadxyz.py +292 -0
  102. webscout/Provider/OPENAI/heckai.py +100 -104
  103. webscout/Provider/OPENAI/huggingface.py +321 -0
  104. webscout/Provider/OPENAI/ibm.py +425 -0
  105. webscout/Provider/OPENAI/llmchat.py +253 -0
  106. webscout/Provider/OPENAI/llmchatco.py +378 -327
  107. webscout/Provider/OPENAI/meta.py +541 -0
  108. webscout/Provider/OPENAI/netwrck.py +110 -84
  109. webscout/Provider/OPENAI/nvidia.py +317 -0
  110. webscout/Provider/OPENAI/oivscode.py +348 -0
  111. webscout/Provider/OPENAI/openrouter.py +328 -0
  112. webscout/Provider/OPENAI/pydantic_imports.py +1 -0
  113. webscout/Provider/OPENAI/sambanova.py +397 -0
  114. webscout/Provider/OPENAI/sonus.py +126 -115
  115. webscout/Provider/OPENAI/textpollinations.py +218 -133
  116. webscout/Provider/OPENAI/toolbaz.py +136 -166
  117. webscout/Provider/OPENAI/typefully.py +419 -0
  118. webscout/Provider/OPENAI/typliai.py +279 -0
  119. webscout/Provider/OPENAI/utils.py +314 -211
  120. webscout/Provider/OPENAI/wisecat.py +103 -125
  121. webscout/Provider/OPENAI/writecream.py +185 -156
  122. webscout/Provider/OPENAI/x0gpt.py +227 -136
  123. webscout/Provider/OPENAI/zenmux.py +380 -0
  124. webscout/Provider/OpenRouter.py +386 -0
  125. webscout/Provider/Openai.py +337 -496
  126. webscout/Provider/PI.py +443 -344
  127. webscout/Provider/QwenLM.py +346 -254
  128. webscout/Provider/STT/__init__.py +28 -0
  129. webscout/Provider/STT/base.py +303 -0
  130. webscout/Provider/STT/elevenlabs.py +264 -0
  131. webscout/Provider/Sambanova.py +317 -0
  132. webscout/Provider/TTI/README.md +69 -0
  133. webscout/Provider/TTI/__init__.py +37 -12
  134. webscout/Provider/TTI/base.py +147 -0
  135. webscout/Provider/TTI/claudeonline.py +393 -0
  136. webscout/Provider/TTI/magicstudio.py +292 -0
  137. webscout/Provider/TTI/miragic.py +180 -0
  138. webscout/Provider/TTI/pollinations.py +331 -0
  139. webscout/Provider/TTI/together.py +334 -0
  140. webscout/Provider/TTI/utils.py +14 -0
  141. webscout/Provider/TTS/README.md +186 -0
  142. webscout/Provider/TTS/__init__.py +43 -7
  143. webscout/Provider/TTS/base.py +523 -0
  144. webscout/Provider/TTS/deepgram.py +286 -156
  145. webscout/Provider/TTS/elevenlabs.py +189 -111
  146. webscout/Provider/TTS/freetts.py +218 -0
  147. webscout/Provider/TTS/murfai.py +288 -113
  148. webscout/Provider/TTS/openai_fm.py +364 -0
  149. webscout/Provider/TTS/parler.py +203 -111
  150. webscout/Provider/TTS/qwen.py +334 -0
  151. webscout/Provider/TTS/sherpa.py +286 -0
  152. webscout/Provider/TTS/speechma.py +693 -180
  153. webscout/Provider/TTS/streamElements.py +275 -333
  154. webscout/Provider/TTS/utils.py +280 -280
  155. webscout/Provider/TextPollinationsAI.py +221 -121
  156. webscout/Provider/TogetherAI.py +450 -0
  157. webscout/Provider/TwoAI.py +309 -199
  158. webscout/Provider/TypliAI.py +311 -0
  159. webscout/Provider/UNFINISHED/ChatHub.py +219 -0
  160. webscout/Provider/{OPENAI/glider.py → UNFINISHED/ChutesAI.py} +160 -145
  161. webscout/Provider/UNFINISHED/GizAI.py +300 -0
  162. webscout/Provider/UNFINISHED/Marcus.py +218 -0
  163. webscout/Provider/UNFINISHED/Qodo.py +481 -0
  164. webscout/Provider/UNFINISHED/XenAI.py +330 -0
  165. webscout/Provider/{Youchat.py → UNFINISHED/Youchat.py} +64 -47
  166. webscout/Provider/UNFINISHED/aihumanizer.py +41 -0
  167. webscout/Provider/UNFINISHED/grammerchecker.py +37 -0
  168. webscout/Provider/UNFINISHED/liner.py +342 -0
  169. webscout/Provider/UNFINISHED/liner_api_request.py +246 -0
  170. webscout/Provider/UNFINISHED/samurai.py +231 -0
  171. webscout/Provider/WiseCat.py +256 -196
  172. webscout/Provider/WrDoChat.py +390 -0
  173. webscout/Provider/__init__.py +115 -198
  174. webscout/Provider/ai4chat.py +181 -202
  175. webscout/Provider/akashgpt.py +330 -342
  176. webscout/Provider/cerebras.py +397 -242
  177. webscout/Provider/cleeai.py +236 -213
  178. webscout/Provider/elmo.py +291 -234
  179. webscout/Provider/geminiapi.py +343 -208
  180. webscout/Provider/julius.py +245 -223
  181. webscout/Provider/learnfastai.py +333 -266
  182. webscout/Provider/llama3mitril.py +230 -180
  183. webscout/Provider/llmchat.py +308 -213
  184. webscout/Provider/llmchatco.py +321 -311
  185. webscout/Provider/meta.py +996 -794
  186. webscout/Provider/oivscode.py +332 -0
  187. webscout/Provider/searchchat.py +316 -293
  188. webscout/Provider/sonus.py +264 -208
  189. webscout/Provider/toolbaz.py +359 -320
  190. webscout/Provider/turboseek.py +332 -219
  191. webscout/Provider/typefully.py +262 -280
  192. webscout/Provider/x0gpt.py +332 -256
  193. webscout/__init__.py +31 -38
  194. webscout/__main__.py +5 -5
  195. webscout/cli.py +585 -293
  196. webscout/client.py +1497 -0
  197. webscout/conversation.py +140 -565
  198. webscout/exceptions.py +383 -339
  199. webscout/litagent/__init__.py +29 -29
  200. webscout/litagent/agent.py +492 -455
  201. webscout/litagent/constants.py +60 -60
  202. webscout/models.py +505 -181
  203. webscout/optimizers.py +32 -378
  204. webscout/prompt_manager.py +376 -274
  205. webscout/sanitize.py +1514 -0
  206. webscout/scout/README.md +452 -0
  207. webscout/scout/__init__.py +8 -8
  208. webscout/scout/core/__init__.py +7 -7
  209. webscout/scout/core/crawler.py +330 -140
  210. webscout/scout/core/scout.py +800 -568
  211. webscout/scout/core/search_result.py +51 -96
  212. webscout/scout/core/text_analyzer.py +64 -63
  213. webscout/scout/core/text_utils.py +412 -277
  214. webscout/scout/core/web_analyzer.py +54 -52
  215. webscout/scout/element.py +872 -460
  216. webscout/scout/parsers/__init__.py +70 -69
  217. webscout/scout/parsers/html5lib_parser.py +182 -172
  218. webscout/scout/parsers/html_parser.py +238 -236
  219. webscout/scout/parsers/lxml_parser.py +203 -178
  220. webscout/scout/utils.py +38 -37
  221. webscout/search/__init__.py +47 -0
  222. webscout/search/base.py +201 -0
  223. webscout/search/bing_main.py +45 -0
  224. webscout/search/brave_main.py +92 -0
  225. webscout/search/duckduckgo_main.py +57 -0
  226. webscout/search/engines/__init__.py +127 -0
  227. webscout/search/engines/bing/__init__.py +15 -0
  228. webscout/search/engines/bing/base.py +35 -0
  229. webscout/search/engines/bing/images.py +114 -0
  230. webscout/search/engines/bing/news.py +96 -0
  231. webscout/search/engines/bing/suggestions.py +36 -0
  232. webscout/search/engines/bing/text.py +109 -0
  233. webscout/search/engines/brave/__init__.py +19 -0
  234. webscout/search/engines/brave/base.py +47 -0
  235. webscout/search/engines/brave/images.py +213 -0
  236. webscout/search/engines/brave/news.py +353 -0
  237. webscout/search/engines/brave/suggestions.py +318 -0
  238. webscout/search/engines/brave/text.py +167 -0
  239. webscout/search/engines/brave/videos.py +364 -0
  240. webscout/search/engines/duckduckgo/__init__.py +25 -0
  241. webscout/search/engines/duckduckgo/answers.py +80 -0
  242. webscout/search/engines/duckduckgo/base.py +189 -0
  243. webscout/search/engines/duckduckgo/images.py +100 -0
  244. webscout/search/engines/duckduckgo/maps.py +183 -0
  245. webscout/search/engines/duckduckgo/news.py +70 -0
  246. webscout/search/engines/duckduckgo/suggestions.py +22 -0
  247. webscout/search/engines/duckduckgo/text.py +221 -0
  248. webscout/search/engines/duckduckgo/translate.py +48 -0
  249. webscout/search/engines/duckduckgo/videos.py +80 -0
  250. webscout/search/engines/duckduckgo/weather.py +84 -0
  251. webscout/search/engines/mojeek.py +61 -0
  252. webscout/search/engines/wikipedia.py +77 -0
  253. webscout/search/engines/yahoo/__init__.py +41 -0
  254. webscout/search/engines/yahoo/answers.py +19 -0
  255. webscout/search/engines/yahoo/base.py +34 -0
  256. webscout/search/engines/yahoo/images.py +323 -0
  257. webscout/search/engines/yahoo/maps.py +19 -0
  258. webscout/search/engines/yahoo/news.py +258 -0
  259. webscout/search/engines/yahoo/suggestions.py +140 -0
  260. webscout/search/engines/yahoo/text.py +273 -0
  261. webscout/search/engines/yahoo/translate.py +19 -0
  262. webscout/search/engines/yahoo/videos.py +302 -0
  263. webscout/search/engines/yahoo/weather.py +220 -0
  264. webscout/search/engines/yandex.py +67 -0
  265. webscout/search/engines/yep/__init__.py +13 -0
  266. webscout/search/engines/yep/base.py +34 -0
  267. webscout/search/engines/yep/images.py +101 -0
  268. webscout/search/engines/yep/suggestions.py +38 -0
  269. webscout/search/engines/yep/text.py +99 -0
  270. webscout/search/http_client.py +172 -0
  271. webscout/search/results.py +141 -0
  272. webscout/search/yahoo_main.py +57 -0
  273. webscout/search/yep_main.py +48 -0
  274. webscout/server/__init__.py +48 -0
  275. webscout/server/config.py +78 -0
  276. webscout/server/exceptions.py +69 -0
  277. webscout/server/providers.py +286 -0
  278. webscout/server/request_models.py +131 -0
  279. webscout/server/request_processing.py +404 -0
  280. webscout/server/routes.py +642 -0
  281. webscout/server/server.py +351 -0
  282. webscout/server/ui_templates.py +1171 -0
  283. webscout/swiftcli/__init__.py +79 -809
  284. webscout/swiftcli/core/__init__.py +7 -0
  285. webscout/swiftcli/core/cli.py +574 -0
  286. webscout/swiftcli/core/context.py +98 -0
  287. webscout/swiftcli/core/group.py +268 -0
  288. webscout/swiftcli/decorators/__init__.py +28 -0
  289. webscout/swiftcli/decorators/command.py +243 -0
  290. webscout/swiftcli/decorators/options.py +247 -0
  291. webscout/swiftcli/decorators/output.py +392 -0
  292. webscout/swiftcli/exceptions.py +21 -0
  293. webscout/swiftcli/plugins/__init__.py +9 -0
  294. webscout/swiftcli/plugins/base.py +134 -0
  295. webscout/swiftcli/plugins/manager.py +269 -0
  296. webscout/swiftcli/utils/__init__.py +58 -0
  297. webscout/swiftcli/utils/formatting.py +251 -0
  298. webscout/swiftcli/utils/parsing.py +368 -0
  299. webscout/update_checker.py +280 -136
  300. webscout/utils.py +28 -14
  301. webscout/version.py +2 -1
  302. webscout/version.py.bak +3 -0
  303. webscout/zeroart/__init__.py +218 -55
  304. webscout/zeroart/base.py +70 -60
  305. webscout/zeroart/effects.py +155 -99
  306. webscout/zeroart/fonts.py +1799 -816
  307. webscout-2026.1.19.dist-info/METADATA +638 -0
  308. webscout-2026.1.19.dist-info/RECORD +312 -0
  309. {webscout-8.2.2.dist-info → webscout-2026.1.19.dist-info}/WHEEL +1 -1
  310. webscout-2026.1.19.dist-info/entry_points.txt +4 -0
  311. webscout-2026.1.19.dist-info/top_level.txt +1 -0
  312. inferno/__init__.py +0 -6
  313. inferno/__main__.py +0 -9
  314. inferno/cli.py +0 -6
  315. webscout/DWEBS.py +0 -477
  316. webscout/Extra/autocoder/__init__.py +0 -9
  317. webscout/Extra/autocoder/autocoder.py +0 -849
  318. webscout/Extra/autocoder/autocoder_utiles.py +0 -332
  319. webscout/LLM.py +0 -442
  320. webscout/Litlogger/__init__.py +0 -67
  321. webscout/Litlogger/core/__init__.py +0 -6
  322. webscout/Litlogger/core/level.py +0 -23
  323. webscout/Litlogger/core/logger.py +0 -165
  324. webscout/Litlogger/handlers/__init__.py +0 -12
  325. webscout/Litlogger/handlers/console.py +0 -33
  326. webscout/Litlogger/handlers/file.py +0 -143
  327. webscout/Litlogger/handlers/network.py +0 -173
  328. webscout/Litlogger/styles/__init__.py +0 -7
  329. webscout/Litlogger/styles/colors.py +0 -249
  330. webscout/Litlogger/styles/formats.py +0 -458
  331. webscout/Litlogger/styles/text.py +0 -87
  332. webscout/Litlogger/utils/__init__.py +0 -6
  333. webscout/Litlogger/utils/detectors.py +0 -153
  334. webscout/Litlogger/utils/formatters.py +0 -200
  335. webscout/Local/__init__.py +0 -12
  336. webscout/Local/__main__.py +0 -9
  337. webscout/Local/api.py +0 -576
  338. webscout/Local/cli.py +0 -516
  339. webscout/Local/config.py +0 -75
  340. webscout/Local/llm.py +0 -287
  341. webscout/Local/model_manager.py +0 -253
  342. webscout/Local/server.py +0 -721
  343. webscout/Local/utils.py +0 -93
  344. webscout/Provider/AI21.py +0 -177
  345. webscout/Provider/AISEARCH/DeepFind.py +0 -250
  346. webscout/Provider/AISEARCH/ISou.py +0 -256
  347. webscout/Provider/AISEARCH/felo_search.py +0 -228
  348. webscout/Provider/AISEARCH/genspark_search.py +0 -208
  349. webscout/Provider/AISEARCH/hika_search.py +0 -194
  350. webscout/Provider/AISEARCH/scira_search.py +0 -324
  351. webscout/Provider/Aitopia.py +0 -292
  352. webscout/Provider/AllenAI.py +0 -413
  353. webscout/Provider/Blackboxai.py +0 -229
  354. webscout/Provider/C4ai.py +0 -432
  355. webscout/Provider/ChatGPTClone.py +0 -226
  356. webscout/Provider/ChatGPTES.py +0 -237
  357. webscout/Provider/ChatGPTGratis.py +0 -194
  358. webscout/Provider/Chatify.py +0 -175
  359. webscout/Provider/Cloudflare.py +0 -273
  360. webscout/Provider/DeepSeek.py +0 -196
  361. webscout/Provider/ElectronHub.py +0 -709
  362. webscout/Provider/ExaChat.py +0 -342
  363. webscout/Provider/Free2GPT.py +0 -241
  364. webscout/Provider/GPTWeb.py +0 -193
  365. webscout/Provider/Glider.py +0 -211
  366. webscout/Provider/HF_space/__init__.py +0 -0
  367. webscout/Provider/HF_space/qwen_qwen2.py +0 -206
  368. webscout/Provider/HuggingFaceChat.py +0 -462
  369. webscout/Provider/Hunyuan.py +0 -272
  370. webscout/Provider/LambdaChat.py +0 -392
  371. webscout/Provider/Llama.py +0 -200
  372. webscout/Provider/Llama3.py +0 -204
  373. webscout/Provider/Marcus.py +0 -148
  374. webscout/Provider/OLLAMA.py +0 -396
  375. webscout/Provider/OPENAI/c4ai.py +0 -367
  376. webscout/Provider/OPENAI/chatgptclone.py +0 -460
  377. webscout/Provider/OPENAI/exachat.py +0 -433
  378. webscout/Provider/OPENAI/freeaichat.py +0 -352
  379. webscout/Provider/OPENAI/opkfc.py +0 -488
  380. webscout/Provider/OPENAI/scirachat.py +0 -463
  381. webscout/Provider/OPENAI/standardinput.py +0 -425
  382. webscout/Provider/OPENAI/typegpt.py +0 -346
  383. webscout/Provider/OPENAI/uncovrAI.py +0 -455
  384. webscout/Provider/OPENAI/venice.py +0 -413
  385. webscout/Provider/OPENAI/yep.py +0 -327
  386. webscout/Provider/OpenGPT.py +0 -199
  387. webscout/Provider/Perplexitylabs.py +0 -415
  388. webscout/Provider/Phind.py +0 -535
  389. webscout/Provider/PizzaGPT.py +0 -198
  390. webscout/Provider/Reka.py +0 -214
  391. webscout/Provider/StandardInput.py +0 -278
  392. webscout/Provider/TTI/AiForce/__init__.py +0 -22
  393. webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
  394. webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
  395. webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
  396. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
  397. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
  398. webscout/Provider/TTI/ImgSys/__init__.py +0 -23
  399. webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
  400. webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
  401. webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
  402. webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
  403. webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
  404. webscout/Provider/TTI/Nexra/__init__.py +0 -22
  405. webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
  406. webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
  407. webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
  408. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
  409. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
  410. webscout/Provider/TTI/aiarta/__init__.py +0 -2
  411. webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
  412. webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
  413. webscout/Provider/TTI/artbit/__init__.py +0 -22
  414. webscout/Provider/TTI/artbit/async_artbit.py +0 -155
  415. webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
  416. webscout/Provider/TTI/fastflux/__init__.py +0 -22
  417. webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
  418. webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
  419. webscout/Provider/TTI/huggingface/__init__.py +0 -22
  420. webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
  421. webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
  422. webscout/Provider/TTI/piclumen/__init__.py +0 -23
  423. webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
  424. webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
  425. webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
  426. webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
  427. webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
  428. webscout/Provider/TTI/talkai/__init__.py +0 -4
  429. webscout/Provider/TTI/talkai/async_talkai.py +0 -229
  430. webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
  431. webscout/Provider/TTS/gesserit.py +0 -127
  432. webscout/Provider/TeachAnything.py +0 -187
  433. webscout/Provider/Venice.py +0 -219
  434. webscout/Provider/VercelAI.py +0 -234
  435. webscout/Provider/WebSim.py +0 -228
  436. webscout/Provider/Writecream.py +0 -211
  437. webscout/Provider/WritingMate.py +0 -197
  438. webscout/Provider/aimathgpt.py +0 -189
  439. webscout/Provider/askmyai.py +0 -158
  440. webscout/Provider/asksteve.py +0 -203
  441. webscout/Provider/bagoodex.py +0 -145
  442. webscout/Provider/chatglm.py +0 -205
  443. webscout/Provider/copilot.py +0 -428
  444. webscout/Provider/freeaichat.py +0 -271
  445. webscout/Provider/gaurish.py +0 -244
  446. webscout/Provider/geminiprorealtime.py +0 -160
  447. webscout/Provider/granite.py +0 -187
  448. webscout/Provider/hermes.py +0 -219
  449. webscout/Provider/koala.py +0 -268
  450. webscout/Provider/labyrinth.py +0 -340
  451. webscout/Provider/lepton.py +0 -194
  452. webscout/Provider/llamatutor.py +0 -192
  453. webscout/Provider/multichat.py +0 -325
  454. webscout/Provider/promptrefine.py +0 -193
  455. webscout/Provider/scira_chat.py +0 -277
  456. webscout/Provider/scnet.py +0 -187
  457. webscout/Provider/talkai.py +0 -194
  458. webscout/Provider/tutorai.py +0 -252
  459. webscout/Provider/typegpt.py +0 -232
  460. webscout/Provider/uncovr.py +0 -312
  461. webscout/Provider/yep.py +0 -376
  462. webscout/litprinter/__init__.py +0 -59
  463. webscout/scout/core.py +0 -881
  464. webscout/tempid.py +0 -128
  465. webscout/webscout_search.py +0 -1346
  466. webscout/webscout_search_async.py +0 -877
  467. webscout/yep_search.py +0 -297
  468. webscout-8.2.2.dist-info/METADATA +0 -734
  469. webscout-8.2.2.dist-info/RECORD +0 -309
  470. webscout-8.2.2.dist-info/entry_points.txt +0 -5
  471. webscout-8.2.2.dist-info/top_level.txt +0 -3
  472. webstoken/__init__.py +0 -30
  473. webstoken/classifier.py +0 -189
  474. webstoken/keywords.py +0 -216
  475. webstoken/language.py +0 -128
  476. webstoken/ner.py +0 -164
  477. webstoken/normalizer.py +0 -35
  478. webstoken/processor.py +0 -77
  479. webstoken/sentiment.py +0 -206
  480. webstoken/stemmer.py +0 -73
  481. webstoken/tagger.py +0 -60
  482. webstoken/tokenizer.py +0 -158
  483. {webscout-8.2.2.dist-info → webscout-2026.1.19.dist-info/licenses}/LICENSE.md +0 -0
@@ -1,108 +1,196 @@
1
- import requests
2
1
  import json
3
- import os
4
- from typing import Any, Dict, Optional, Generator, Union
2
+ from typing import Any, Dict, Generator, Optional, Union, cast
3
+
4
+ from curl_cffi import CurlError
5
+ from curl_cffi.requests import Session
5
6
 
6
- from webscout.AIutel import Optimizers
7
- from webscout.AIutel import Conversation
8
- from webscout.AIutel import AwesomePrompts, sanitize_stream
9
- from webscout.AIbase import Provider, AsyncProvider
10
7
  from webscout import exceptions
8
+ from webscout.AIbase import Provider, Response
9
+ from webscout.AIutel import AwesomePrompts, Conversation, Optimizers, sanitize_stream
11
10
  from webscout.litagent import LitAgent
12
11
 
12
+
13
13
  class DeepInfra(Provider):
14
14
  """
15
15
  A class to interact with the DeepInfra API with LitAgent user-agent.
16
16
  """
17
17
 
18
+ required_auth = False
19
+ # Default models list (will be updated dynamically)
18
20
  AVAILABLE_MODELS = [
19
- # "anthropic/claude-3-7-sonnet-latest", # >>>> NOT WORKING
20
-
21
- "deepseek-ai/DeepSeek-R1",
22
- "deepseek-ai/DeepSeek-R1-Distill-Llama-70B",
23
- "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
24
- "deepseek-ai/DeepSeek-R1-Turbo",
25
- "deepseek-ai/DeepSeek-V3",
26
-
27
- "google/gemma-2-27b-it",
28
- "google/gemma-2-9b-it",
21
+ "moonshotai/Kimi-K2-Instruct",
22
+ "moonshotai/Kimi-K2-Thinking",
23
+ "MiniMaxAI/MiniMax-M2",
24
+ "Qwen/Qwen3-Next-80B-A3B-Instruct",
25
+ "Qwen/Qwen3-Next-80B-A3B-Thinking",
26
+ "moonshotai/Kimi-K2-Instruct-0905",
27
+ "Qwen/Qwen3-Coder-30B-A3B-Instruct",
28
+ "deepseek-ai/DeepSeek-R1-0528-Turbo",
29
+ "Qwen/Qwen3-235B-A22B-Thinking-2507",
30
+ "deepseek-ai/DeepSeek-V3.1-Terminus",
31
+ "deepseek-ai/DeepSeek-V3.2-Exp",
32
+ "Qwen/Qwen3-Coder-480B-A35B-Instruct",
33
+ "Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo",
34
+ "Qwen/Qwen3-235B-A22B-Instruct-2507",
35
+ "Qwen/Qwen3-235B-A22B",
36
+ "Qwen/Qwen3-30B-A3B",
37
+ "Qwen/Qwen3-32B",
38
+ "Qwen/Qwen3-14B",
39
+ "deepseek-ai/DeepSeek-V3-0324-Turbo",
40
+ "deepseek-ai/DeepSeek-Prover-V2-671B",
41
+ "meta-llama/Llama-4-Maverick-17B-128E-Instruct-Turbo",
42
+ "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8",
43
+ "meta-llama/Llama-4-Scout-17B-16E-Instruct",
44
+ "deepseek-ai/DeepSeek-R1-0528",
45
+ "deepseek-ai/DeepSeek-V3-0324",
46
+ "mistralai/Mistral-Small-3.1-24B-Instruct-2503",
47
+ "microsoft/phi-4-reasoning-plus",
48
+ "Qwen/QwQ-32B",
29
49
  "google/gemma-3-27b-it",
30
50
  "google/gemma-3-12b-it",
31
51
  "google/gemma-3-4b-it",
32
- # "google/gemini-1.5-flash", # >>>> NOT WORKING
33
- # "google/gemini-1.5-flash-8b", # >>>> NOT WORKING
34
- # "google/gemini-2.0-flash-001", # >>>> NOT WORKING
35
-
36
- # "Gryphe/MythoMax-L2-13b", # >>>> NOT WORKING
37
-
38
- # "meta-llama/Llama-3.2-1B-Instruct", # >>>> NOT WORKING
39
- # "meta-llama/Llama-3.2-3B-Instruct", # >>>> NOT WORKING
40
- "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8",
41
- "meta-llama/Llama-4-Scout-17B-16E-Instruct",
42
- # "meta-llama/Llama-3.2-90B-Vision-Instruct", # >>>> NOT WORKING
43
- # "meta-llama/Llama-3.2-11B-Vision-Instruct", # >>>> NOT WORKING
44
- "meta-llama/Llama-3.3-70B-Instruct",
52
+ "microsoft/Phi-4-multimodal-instruct",
53
+ "deepseek-ai/DeepSeek-R1-Distill-Llama-70B",
54
+ "deepseek-ai/DeepSeek-V3",
55
+ "deepseek-ai/DeepSeek-V3.1",
45
56
  "meta-llama/Llama-3.3-70B-Instruct-Turbo",
46
- # "meta-llama/Meta-Llama-3-70B-Instruct", # >>>> NOT WORKING
47
- # "meta-llama/Meta-Llama-3-8B-Instruct", # >>>> NOT WORKING
48
- # "meta-llama/Meta-Llama-3.1-70B-Instruct", # >>>> NOT WORKING
49
- # "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo", # >>>> NOT WORKING
57
+ "meta-llama/Llama-3.3-70B-Instruct",
58
+ "microsoft/phi-4",
59
+ "Gryphe/MythoMax-L2-13b",
60
+ "NousResearch/Hermes-3-Llama-3.1-405B",
61
+ "NousResearch/Hermes-3-Llama-3.1-70B",
62
+ "NovaSky-AI/Sky-T1-32B-Preview",
63
+ "Qwen/Qwen2.5-72B-Instruct",
64
+ "Qwen/Qwen2.5-7B-Instruct",
65
+ "Qwen/Qwen2.5-Coder-32B-Instruct",
66
+ "Sao10K/L3-8B-Lunaris-v1-Turbo",
67
+ "Sao10K/L3.1-70B-Euryale-v2.2",
68
+ "Sao10K/L3.3-70B-Euryale-v2.3",
69
+ "deepseek-ai/DeepSeek-R1",
70
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
71
+ "deepseek-ai/DeepSeek-R1-Turbo",
72
+ "google/gemini-2.0-flash-001",
73
+ "meta-llama/Llama-3.2-11B-Vision-Instruct",
74
+ "meta-llama/Llama-3.2-1B-Instruct",
75
+ "meta-llama/Llama-3.2-3B-Instruct",
76
+ "meta-llama/Llama-3.2-90B-Vision-Instruct",
77
+ "meta-llama/Meta-Llama-3-70B-Instruct",
78
+ "meta-llama/Meta-Llama-3-8B-Instruct",
79
+ "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
50
80
  "meta-llama/Meta-Llama-3.1-8B-Instruct",
51
81
  "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
52
- # "meta-llama/Meta-Llama-3.1-405B-Instruct", # >>>> NOT WORKING
53
-
54
- "microsoft/phi-4",
55
- "microsoft/Phi-4-multimodal-instruct",
56
82
  "microsoft/WizardLM-2-8x22B",
57
- # "mistralai/Mixtral-8x7B-Instruct-v0.1", # >>>> NOT WORKING
58
- # "mistralai/Mistral-7B-Instruct-v0.3", # >>>> NOT WORKING
59
- # "mistralai/Mistral-Nemo-Instruct-2407", # >>>> NOT WORKING
83
+ "mistralai/Devstral-Small-2505",
84
+ "mistralai/Devstral-Small-2507",
85
+ "mistralai/Mistral-7B-Instruct-v0.3",
86
+ "mistralai/Mistral-Nemo-Instruct-2407",
60
87
  "mistralai/Mistral-Small-24B-Instruct-2501",
88
+ "mistralai/Mistral-Small-3.2-24B-Instruct-2506",
89
+ "mistralai/Mixtral-8x7B-Instruct-v0.1",
61
90
  "nvidia/Llama-3.1-Nemotron-70B-Instruct",
62
- # "NousResearch/Hermes-3-Llama-3.1-405B", # >>>> NOT WORKING
63
- # "NovaSky-AI/Sky-T1-32B-Preview", # >>>> NOT WORKING
64
- "Qwen/QwQ-32B",
65
- # "Qwen/Qwen2.5-7B-Instruct", # >>>> NOT WORKING
66
- "Qwen/Qwen2.5-72B-Instruct",
67
- "Qwen/Qwen2.5-Coder-32B-Instruct",
68
- # "Sao10K/L3.1-70B-Euryale-v2.2", # >>>> NOT WORKING
69
- # "Sao10K/L3.3-70B-Euryale-v2.3", # >>>> NOT WORKING
91
+ "nvidia/Nemotron-3-Nano-30B-A3B",
92
+ "zai-org/GLM-4.5-Air",
93
+ "zai-org/GLM-4.5",
94
+ "zai-org/GLM-4.5V",
95
+ "zai-org/GLM-4.6",
96
+ "openai/gpt-oss-120b",
97
+ "openai/gpt-oss-20b",
98
+ "allenai/olmOCR-7B-0725-FP8",
70
99
  ]
71
100
 
101
+ @classmethod
102
+ def get_models(cls, api_key: Optional[str] = None):
103
+ """Fetch available models from DeepInfra API.
104
+
105
+ Args:
106
+ api_key (str, optional): DeepInfra API key. If not provided, returns default models.
107
+
108
+ Returns:
109
+ list: List of available model IDs
110
+ """
111
+ if not api_key:
112
+ return cls.AVAILABLE_MODELS
113
+
114
+ try:
115
+ # Use a temporary curl_cffi session for this class method
116
+ temp_session = Session()
117
+ headers = {
118
+ "Content-Type": "application/json",
119
+ }
120
+ if api_key:
121
+ headers["Authorization"] = f"Bearer {api_key}"
122
+
123
+ response = temp_session.get(
124
+ "https://api.deepinfra.com/v1/models",
125
+ headers=headers,
126
+ impersonate="chrome110", # Use impersonate for fetching
127
+ )
128
+
129
+ if response.status_code != 200:
130
+ return cls.AVAILABLE_MODELS
131
+
132
+ data = response.json()
133
+ if "data" in data and isinstance(data["data"], list):
134
+ return [model["id"] for model in data["data"]]
135
+ return cls.AVAILABLE_MODELS
136
+
137
+ except (CurlError, Exception):
138
+ # Fallback to default models list if fetching fails
139
+ return cls.AVAILABLE_MODELS
140
+
141
+ @classmethod
142
+ def update_available_models(cls, api_key=None):
143
+ """Update the available models list from DeepInfra API"""
144
+ try:
145
+ models = cls.get_models(api_key)
146
+ if models and len(models) > 0:
147
+ cls.AVAILABLE_MODELS = models
148
+ except Exception:
149
+ # Fallback to default models list if fetching fails
150
+ pass
151
+
152
+ @staticmethod
153
+ def _deepinfra_extractor(chunk: Union[str, Dict[str, Any]]) -> Optional[str]:
154
+ """Extracts content from DeepInfra stream JSON objects."""
155
+ if isinstance(chunk, dict):
156
+ choices = chunk.get("choices")
157
+ if choices:
158
+ return choices[0].get("delta", {}).get("content")
159
+ return None
160
+
72
161
  def __init__(
73
162
  self,
163
+ api_key: Optional[str] = None,
74
164
  is_conversation: bool = True,
75
- max_tokens: int = 2049, # Set a reasonable default
165
+ max_tokens: int = 2049,
76
166
  timeout: int = 30,
77
- intro: str = None,
78
- filepath: str = None,
167
+ intro: Optional[str] = None,
168
+ filepath: Optional[str] = None,
79
169
  update_file: bool = True,
80
170
  proxies: dict = {},
81
171
  history_offset: int = 10250,
82
- act: str = None,
172
+ act: Optional[str] = None,
83
173
  model: str = "meta-llama/Llama-3.3-70B-Instruct-Turbo",
84
174
  system_prompt: str = "You are a helpful assistant.",
85
- browser: str = "chrome"
175
+ browser: str = "chrome",
86
176
  ):
87
177
  """Initializes the DeepInfra API client."""
178
+ # Update available models from API
179
+ self.update_available_models(api_key)
180
+
88
181
  if model not in self.AVAILABLE_MODELS:
89
182
  raise ValueError(f"Invalid model: {model}. Choose from: {self.AVAILABLE_MODELS}")
90
-
183
+
91
184
  self.url = "https://api.deepinfra.com/v1/openai/chat/completions"
92
-
93
- # Initialize LitAgent for user agent generation
185
+
94
186
  self.agent = LitAgent()
95
- # Use fingerprinting to create a consistent browser identity
96
187
  self.fingerprint = self.agent.generate_fingerprint(browser)
97
-
98
- # Use the fingerprint for headers
188
+ self.api = api_key
99
189
  self.headers = {
100
190
  "Accept": self.fingerprint["accept"],
101
- "Accept-Encoding": "gzip, deflate, br, zstd",
102
191
  "Accept-Language": self.fingerprint["accept_language"],
103
192
  "Content-Type": "application/json",
104
193
  "Cache-Control": "no-cache",
105
- "Connection": "keep-alive",
106
194
  "Origin": "https://deepinfra.com",
107
195
  "Pragma": "no-cache",
108
196
  "Referer": "https://deepinfra.com/",
@@ -110,15 +198,24 @@ class DeepInfra(Provider):
110
198
  "Sec-Fetch-Mode": "cors",
111
199
  "Sec-Fetch-Site": "same-site",
112
200
  "X-Deepinfra-Source": "web-embed",
113
- "Sec-CH-UA": self.fingerprint["sec_ch_ua"] or '"Not)A;Brand";v="99", "Microsoft Edge";v="127", "Chromium";v="127"',
201
+ "User-Agent": self.fingerprint.get("user_agent", ""),
202
+ "Sec-CH-UA": self.fingerprint.get("sec_ch_ua", ""),
114
203
  "Sec-CH-UA-Mobile": "?0",
115
- "Sec-CH-UA-Platform": f'"{self.fingerprint["platform"]}"',
116
- "User-Agent": self.fingerprint["user_agent"],
204
+ "Sec-CH-UA-Platform": f'"{self.fingerprint.get("platform", "")}"',
205
+ "X-Forwarded-For": self.fingerprint.get("x-forwarded-for", ""),
206
+ "X-Real-IP": self.fingerprint.get("x-real-ip", ""),
207
+ "X-Client-IP": self.fingerprint.get("x-client-ip", ""),
208
+ "Forwarded": self.fingerprint.get("forwarded", ""),
209
+ "X-Forwarded-Proto": self.fingerprint.get("x-forwarded-proto", ""),
210
+ "X-Request-Id": self.fingerprint.get("x-request-id", ""),
117
211
  }
118
-
119
- self.session = requests.Session()
212
+ if self.api is not None:
213
+ self.headers["Authorization"] = f"Bearer {self.api}"
214
+
215
+ self.session = Session()
120
216
  self.session.headers.update(self.headers)
121
- self.session.proxies.update(proxies)
217
+ if proxies:
218
+ self.session.proxies.update(proxies)
122
219
  self.system_prompt = system_prompt
123
220
  self.is_conversation = is_conversation
124
221
  self.max_tokens_to_sample = max_tokens
@@ -131,42 +228,36 @@ class DeepInfra(Provider):
131
228
  for method in dir(Optimizers)
132
229
  if callable(getattr(Optimizers, method)) and not method.startswith("__")
133
230
  )
134
- Conversation.intro = (
135
- AwesomePrompts().get_act(
136
- act, raise_not_found=True, default=None, case_insensitive=True
137
- )
138
- if act
139
- else intro or Conversation.intro
140
- )
141
-
142
231
  self.conversation = Conversation(
143
232
  is_conversation, self.max_tokens_to_sample, filepath, update_file
144
233
  )
145
234
  self.conversation.history_offset = history_offset
146
235
 
147
- def refresh_identity(self, browser: str = None):
236
+ if act:
237
+ self.conversation.intro = AwesomePrompts().get_act(cast(Union[str, int], act), default=self.conversation.intro, case_insensitive=True
238
+ ) or self.conversation.intro
239
+ elif intro:
240
+ self.conversation.intro = intro
241
+
242
+ def refresh_identity(self, browser: Optional[str] = None):
148
243
  """
149
244
  Refreshes the browser identity fingerprint.
150
-
245
+
151
246
  Args:
152
247
  browser: Specific browser to use for the new fingerprint
153
248
  """
154
249
  browser = browser or self.fingerprint.get("browser_type", "chrome")
155
250
  self.fingerprint = self.agent.generate_fingerprint(browser)
156
-
157
- # Update headers with new fingerprint
158
- self.headers.update({
159
- "Accept": self.fingerprint["accept"],
160
- "Accept-Language": self.fingerprint["accept_language"],
161
- "Sec-CH-UA": self.fingerprint["sec_ch_ua"] or self.headers["Sec-CH-UA"],
162
- "Sec-CH-UA-Platform": f'"{self.fingerprint["platform"]}"',
163
- "User-Agent": self.fingerprint["user_agent"],
164
- })
165
-
166
- # Update session headers
167
- for header, value in self.headers.items():
168
- self.session.headers[header] = value
169
-
251
+
252
+ self.headers.update(
253
+ {
254
+ "Accept": self.fingerprint["accept"],
255
+ "Accept-Language": self.fingerprint["accept_language"],
256
+ }
257
+ )
258
+
259
+ self.session.headers.update(self.headers)
260
+
170
261
  return self.fingerprint
171
262
 
172
263
  def ask(
@@ -174,9 +265,42 @@ class DeepInfra(Provider):
174
265
  prompt: str,
175
266
  stream: bool = False,
176
267
  raw: bool = False,
177
- optimizer: str = None,
268
+ optimizer: Optional[str] = None,
178
269
  conversationally: bool = False,
179
- ) -> Union[Dict[str, Any], Generator]:
270
+ **kwargs: Any,
271
+ ) -> Response:
272
+ """
273
+ Sends a prompt to the DeepInfra API and returns the response.
274
+
275
+ Args:
276
+ prompt: The prompt to send to the API
277
+ stream: Whether to stream the response
278
+ raw: If True, returns unprocessed response chunks without any
279
+ processing or sanitization. Useful for debugging or custom
280
+ processing pipelines. Defaults to False.
281
+ optimizer: Optional prompt optimizer name
282
+ conversationally: Whether to use conversation context
283
+
284
+ Returns:
285
+ When raw=False: Dict with 'text' key (non-streaming) or
286
+ Generator yielding dicts (streaming)
287
+ When raw=True: Raw string response (non-streaming) or
288
+ Generator yielding raw string chunks (streaming)
289
+
290
+ Examples:
291
+ >>> ai = DeepInfra()
292
+ >>> # Get processed response
293
+ >>> response = ai.ask("Hello")
294
+ >>> print(response["text"])
295
+
296
+ >>> # Get raw response
297
+ >>> raw_response = ai.ask("Hello", raw=True)
298
+ >>> print(raw_response)
299
+
300
+ >>> # Stream raw chunks
301
+ >>> for chunk in ai.ask("Hello", stream=True, raw=True):
302
+ ... print(chunk, end='', flush=True)
303
+ """
180
304
  conversation_prompt = self.conversation.gen_complete_prompt(prompt)
181
305
  if optimizer:
182
306
  if optimizer in self.__available_optimizers:
@@ -186,68 +310,110 @@ class DeepInfra(Provider):
186
310
  else:
187
311
  raise Exception(f"Optimizer is not one of {self.__available_optimizers}")
188
312
 
189
- # Payload construction
190
313
  payload = {
191
314
  "model": self.model,
192
315
  "messages": [
193
316
  {"role": "system", "content": self.system_prompt},
194
317
  {"role": "user", "content": conversation_prompt},
195
318
  ],
196
- "stream": stream
319
+ "stream": stream,
197
320
  }
198
321
 
199
322
  def for_stream():
323
+ streaming_text = ""
200
324
  try:
201
- with requests.post(self.url, headers=self.headers, data=json.dumps(payload), stream=True, timeout=self.timeout) as response:
202
- if response.status_code != 200:
203
- raise exceptions.FailedToGenerateResponseError(
204
- f"Request failed with status code {response.status_code}"
205
- )
206
-
207
- streaming_text = ""
208
- for line in response.iter_lines(decode_unicode=True):
209
- if line:
210
- line = line.strip()
211
- if line.startswith("data: "):
212
- json_str = line[6:]
213
- if json_str == "[DONE]":
214
- break
215
- try:
216
- json_data = json.loads(json_str)
217
- if 'choices' in json_data:
218
- choice = json_data['choices'][0]
219
- if 'delta' in choice and 'content' in choice['delta']:
220
- content = choice['delta']['content']
221
- streaming_text += content
222
- resp = dict(text=content)
223
- yield resp if raw else resp
224
- except json.JSONDecodeError:
225
- continue
226
-
325
+ response = self.session.post(
326
+ self.url,
327
+ data=json.dumps(payload),
328
+ stream=True,
329
+ timeout=self.timeout,
330
+ impersonate="chrome110",
331
+ )
332
+ response.raise_for_status()
333
+
334
+ processed_stream = sanitize_stream(
335
+ data=response.iter_content(chunk_size=None),
336
+ intro_value="data:",
337
+ to_json=True,
338
+ skip_markers=["[DONE]"],
339
+ content_extractor=self._deepinfra_extractor,
340
+ yield_raw_on_error=False,
341
+ raw=raw,
342
+ )
343
+
344
+ for content_chunk in processed_stream:
345
+ if isinstance(content_chunk, bytes):
346
+ content_chunk = content_chunk.decode("utf-8", errors="ignore")
347
+
348
+ if raw:
349
+ yield content_chunk
350
+ else:
351
+ if content_chunk and isinstance(content_chunk, str):
352
+ streaming_text += content_chunk
353
+ yield dict(text=content_chunk)
354
+
355
+ except CurlError as e:
356
+ raise exceptions.FailedToGenerateResponseError(
357
+ f"Request failed (CurlError): {str(e)}"
358
+ ) from e
359
+ except Exception as e:
360
+ raise exceptions.FailedToGenerateResponseError(
361
+ f"Request failed ({type(e).__name__}): {str(e)}"
362
+ ) from e
363
+ finally:
364
+ if not raw and streaming_text:
227
365
  self.last_response = {"text": streaming_text}
228
366
  self.conversation.update_chat_history(prompt, streaming_text)
229
-
230
- except requests.RequestException as e:
231
- raise exceptions.FailedToGenerateResponseError(f"Request failed: {str(e)}")
232
367
 
233
368
  def for_non_stream():
234
369
  try:
235
- response = requests.post(self.url, headers=self.headers, data=json.dumps(payload), timeout=self.timeout)
236
- if response.status_code != 200:
237
- raise exceptions.FailedToGenerateResponseError(
238
- f"Request failed with status code {response.status_code}"
239
- )
240
-
241
- response_data = response.json()
242
- if 'choices' in response_data and len(response_data['choices']) > 0:
243
- content = response_data['choices'][0].get('message', {}).get('content', '')
244
- self.last_response = {"text": content}
245
- self.conversation.update_chat_history(prompt, content)
246
- return {"text": content}
247
- else:
248
- raise exceptions.FailedToGenerateResponseError("No response content found")
370
+ response = self.session.post(
371
+ self.url,
372
+ data=json.dumps(payload),
373
+ timeout=self.timeout,
374
+ impersonate="chrome110",
375
+ )
376
+ response.raise_for_status()
377
+
378
+ if raw:
379
+ return response.text
380
+
381
+ # Use sanitize_stream to parse the non-streaming JSON response
382
+ processed_stream = sanitize_stream(
383
+ data=response.text,
384
+ to_json=True,
385
+ intro_value=None,
386
+ content_extractor=lambda chunk: chunk.get("choices", [{}])[0]
387
+ .get("message", {})
388
+ .get("content")
389
+ if isinstance(chunk, dict)
390
+ else None,
391
+ yield_raw_on_error=False,
392
+ raw=raw,
393
+ )
394
+ # Extract the single result
395
+ content = next(processed_stream, None)
396
+ if raw:
397
+ return content
398
+ content = content if isinstance(content, str) else ""
399
+
400
+ self.last_response = {"text": content}
401
+ self.conversation.update_chat_history(prompt, content)
402
+ return self.last_response if not raw else content
403
+
404
+ except CurlError as e:
405
+ raise exceptions.FailedToGenerateResponseError(
406
+ f"Request failed (CurlError): {e}"
407
+ ) from e
249
408
  except Exception as e:
250
- raise exceptions.FailedToGenerateResponseError(f"Request failed: {e}")
409
+ err_text = ""
410
+ if hasattr(e, 'response'):
411
+ response_obj = getattr(e, 'response')
412
+ if hasattr(response_obj, 'text'):
413
+ err_text = getattr(response_obj, 'text')
414
+ raise exceptions.FailedToGenerateResponseError(
415
+ f"Request failed ({type(e).__name__}): {e} - {err_text}"
416
+ ) from e
251
417
 
252
418
  return for_stream() if stream else for_non_stream()
253
419
 
@@ -255,43 +421,47 @@ class DeepInfra(Provider):
255
421
  self,
256
422
  prompt: str,
257
423
  stream: bool = False,
258
- optimizer: str = None,
424
+ optimizer: Optional[str] = None,
259
425
  conversationally: bool = False,
426
+ **kwargs: Any,
260
427
  ) -> Union[str, Generator[str, None, None]]:
261
- def for_stream():
262
- for response in self.ask(prompt, True, optimizer=optimizer, conversationally=conversationally):
263
- yield self.get_message(response)
264
- def for_non_stream():
265
- return self.get_message(
266
- self.ask(prompt, False, optimizer=optimizer, conversationally=conversationally)
428
+ raw = kwargs.get("raw", False)
429
+ if stream:
430
+ def for_stream_chat():
431
+ gen = self.ask(
432
+ prompt, stream=True, raw=raw, optimizer=optimizer, conversationally=conversationally
433
+ )
434
+ if hasattr(gen, "__iter__"):
435
+ for response in gen:
436
+ if raw:
437
+ yield cast(str, response)
438
+ else:
439
+ yield self.get_message(response)
440
+ return for_stream_chat()
441
+ else:
442
+ result = self.ask(
443
+ prompt,
444
+ stream=False,
445
+ raw=raw,
446
+ optimizer=optimizer,
447
+ conversationally=conversationally,
267
448
  )
268
- return for_stream() if stream else for_non_stream()
449
+ if raw:
450
+ return cast(str, result)
451
+ else:
452
+ return self.get_message(result)
269
453
 
270
- def get_message(self, response: dict) -> str:
271
- assert isinstance(response, dict), "Response should be of dict data-type only"
454
+ def get_message(self, response: Response) -> str:
455
+ if not isinstance(response, dict):
456
+ return str(response)
272
457
  return response["text"]
273
458
 
274
- if __name__ == "__main__":
275
- print("-" * 80)
276
- print(f"{'Model':<50} {'Status':<10} {'Response'}")
277
- print("-" * 80)
278
459
 
279
- for model in DeepInfra.AVAILABLE_MODELS:
280
- try:
281
- test_ai = DeepInfra(model=model, timeout=60)
282
- response = test_ai.chat("Say 'Hello' in one word", stream=True)
283
- response_text = ""
284
- for chunk in response:
285
- response_text += chunk
286
-
287
- if response_text and len(response_text.strip()) > 0:
288
- status = "✓"
289
- # Clean and truncate response
290
- clean_text = response_text.strip().encode('utf-8', errors='ignore').decode('utf-8')
291
- display_text = clean_text[:50] + "..." if len(clean_text) > 50 else clean_text
292
- else:
293
- status = "✗"
294
- display_text = "Empty or invalid response"
295
- print(f"\r{model:<50} {status:<10} {display_text}")
296
- except Exception as e:
297
- print(f"\r{model:<50} {'✗':<10} {str(e)}")
460
+ if __name__ == "__main__":
461
+ ai = DeepInfra()
462
+ response = ai.chat("Hello", raw=False, stream=True)
463
+ if hasattr(response, "__iter__") and not isinstance(response, (str, bytes)):
464
+ for chunk in response:
465
+ print(chunk, end="")
466
+ else:
467
+ print(response)