webscout 8.3.7__py3-none-any.whl → 2025.10.13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of webscout might be problematic. Click here for more details.
- webscout/AIauto.py +250 -250
- webscout/AIbase.py +379 -379
- webscout/AIutel.py +60 -60
- webscout/Bard.py +1012 -1012
- webscout/Bing_search.py +417 -417
- webscout/DWEBS.py +529 -529
- webscout/Extra/Act.md +309 -309
- webscout/Extra/GitToolkit/__init__.py +10 -10
- webscout/Extra/GitToolkit/gitapi/README.md +110 -110
- webscout/Extra/GitToolkit/gitapi/__init__.py +11 -11
- webscout/Extra/GitToolkit/gitapi/repository.py +195 -195
- webscout/Extra/GitToolkit/gitapi/user.py +96 -96
- webscout/Extra/GitToolkit/gitapi/utils.py +61 -61
- webscout/Extra/YTToolkit/README.md +375 -375
- webscout/Extra/YTToolkit/YTdownloader.py +956 -956
- webscout/Extra/YTToolkit/__init__.py +2 -2
- webscout/Extra/YTToolkit/transcriber.py +475 -475
- webscout/Extra/YTToolkit/ytapi/README.md +44 -44
- webscout/Extra/YTToolkit/ytapi/__init__.py +6 -6
- webscout/Extra/YTToolkit/ytapi/channel.py +307 -307
- webscout/Extra/YTToolkit/ytapi/errors.py +13 -13
- webscout/Extra/YTToolkit/ytapi/extras.py +118 -118
- webscout/Extra/YTToolkit/ytapi/https.py +88 -88
- webscout/Extra/YTToolkit/ytapi/patterns.py +61 -61
- webscout/Extra/YTToolkit/ytapi/playlist.py +58 -58
- webscout/Extra/YTToolkit/ytapi/pool.py +7 -7
- webscout/Extra/YTToolkit/ytapi/query.py +39 -39
- webscout/Extra/YTToolkit/ytapi/stream.py +62 -62
- webscout/Extra/YTToolkit/ytapi/utils.py +62 -62
- webscout/Extra/YTToolkit/ytapi/video.py +232 -232
- webscout/Extra/autocoder/__init__.py +9 -9
- webscout/Extra/autocoder/autocoder.py +1105 -1105
- webscout/Extra/autocoder/autocoder_utiles.py +332 -332
- webscout/Extra/gguf.md +429 -429
- webscout/Extra/gguf.py +1213 -1213
- webscout/Extra/tempmail/README.md +487 -487
- webscout/Extra/tempmail/__init__.py +27 -27
- webscout/Extra/tempmail/async_utils.py +140 -140
- webscout/Extra/tempmail/base.py +160 -160
- webscout/Extra/tempmail/cli.py +186 -186
- webscout/Extra/tempmail/emailnator.py +84 -84
- webscout/Extra/tempmail/mail_tm.py +360 -360
- webscout/Extra/tempmail/temp_mail_io.py +291 -291
- webscout/Extra/weather.md +281 -281
- webscout/Extra/weather.py +193 -193
- webscout/Litlogger/README.md +10 -10
- webscout/Litlogger/__init__.py +15 -15
- webscout/Litlogger/formats.py +13 -13
- webscout/Litlogger/handlers.py +121 -121
- webscout/Litlogger/levels.py +13 -13
- webscout/Litlogger/logger.py +134 -134
- webscout/Provider/AISEARCH/Perplexity.py +332 -332
- webscout/Provider/AISEARCH/README.md +279 -279
- webscout/Provider/AISEARCH/__init__.py +16 -1
- webscout/Provider/AISEARCH/felo_search.py +206 -206
- webscout/Provider/AISEARCH/genspark_search.py +323 -323
- webscout/Provider/AISEARCH/hika_search.py +185 -185
- webscout/Provider/AISEARCH/iask_search.py +410 -410
- webscout/Provider/AISEARCH/monica_search.py +219 -219
- webscout/Provider/AISEARCH/scira_search.py +316 -316
- webscout/Provider/AISEARCH/stellar_search.py +177 -177
- webscout/Provider/AISEARCH/webpilotai_search.py +255 -255
- webscout/Provider/Aitopia.py +314 -314
- webscout/Provider/Andi.py +1 -1
- webscout/Provider/Apriel.py +306 -0
- webscout/Provider/ChatGPTClone.py +237 -236
- webscout/Provider/ChatSandbox.py +343 -343
- webscout/Provider/Cloudflare.py +324 -324
- webscout/Provider/Cohere.py +208 -208
- webscout/Provider/Deepinfra.py +370 -366
- webscout/Provider/ExaAI.py +260 -260
- webscout/Provider/ExaChat.py +308 -308
- webscout/Provider/Flowith.py +221 -221
- webscout/Provider/GMI.py +293 -0
- webscout/Provider/Gemini.py +164 -164
- webscout/Provider/GeminiProxy.py +167 -167
- webscout/Provider/GithubChat.py +371 -372
- webscout/Provider/Groq.py +800 -800
- webscout/Provider/HeckAI.py +383 -383
- webscout/Provider/Jadve.py +282 -282
- webscout/Provider/K2Think.py +307 -307
- webscout/Provider/Koboldai.py +205 -205
- webscout/Provider/LambdaChat.py +423 -423
- webscout/Provider/Nemotron.py +244 -244
- webscout/Provider/Netwrck.py +248 -248
- webscout/Provider/OLLAMA.py +395 -395
- webscout/Provider/OPENAI/Cloudflare.py +393 -393
- webscout/Provider/OPENAI/FalconH1.py +451 -451
- webscout/Provider/OPENAI/FreeGemini.py +296 -296
- webscout/Provider/OPENAI/K2Think.py +431 -431
- webscout/Provider/OPENAI/NEMOTRON.py +240 -240
- webscout/Provider/OPENAI/PI.py +427 -427
- webscout/Provider/OPENAI/README.md +959 -959
- webscout/Provider/OPENAI/TogetherAI.py +345 -345
- webscout/Provider/OPENAI/TwoAI.py +465 -465
- webscout/Provider/OPENAI/__init__.py +33 -18
- webscout/Provider/OPENAI/base.py +248 -248
- webscout/Provider/OPENAI/chatglm.py +528 -0
- webscout/Provider/OPENAI/chatgpt.py +592 -592
- webscout/Provider/OPENAI/chatgptclone.py +521 -521
- webscout/Provider/OPENAI/chatsandbox.py +202 -202
- webscout/Provider/OPENAI/deepinfra.py +318 -314
- webscout/Provider/OPENAI/e2b.py +1665 -1665
- webscout/Provider/OPENAI/exaai.py +420 -420
- webscout/Provider/OPENAI/exachat.py +452 -452
- webscout/Provider/OPENAI/friendli.py +232 -232
- webscout/Provider/OPENAI/{refact.py → gmi.py} +324 -274
- webscout/Provider/OPENAI/groq.py +364 -364
- webscout/Provider/OPENAI/heckai.py +314 -314
- webscout/Provider/OPENAI/llmchatco.py +337 -337
- webscout/Provider/OPENAI/netwrck.py +355 -355
- webscout/Provider/OPENAI/oivscode.py +290 -290
- webscout/Provider/OPENAI/opkfc.py +518 -518
- webscout/Provider/OPENAI/pydantic_imports.py +1 -1
- webscout/Provider/OPENAI/scirachat.py +535 -535
- webscout/Provider/OPENAI/sonus.py +308 -308
- webscout/Provider/OPENAI/standardinput.py +442 -442
- webscout/Provider/OPENAI/textpollinations.py +340 -340
- webscout/Provider/OPENAI/toolbaz.py +419 -416
- webscout/Provider/OPENAI/typefully.py +362 -362
- webscout/Provider/OPENAI/utils.py +295 -295
- webscout/Provider/OPENAI/venice.py +436 -436
- webscout/Provider/OPENAI/wisecat.py +387 -387
- webscout/Provider/OPENAI/writecream.py +166 -166
- webscout/Provider/OPENAI/x0gpt.py +378 -378
- webscout/Provider/OPENAI/yep.py +389 -389
- webscout/Provider/OpenGPT.py +230 -230
- webscout/Provider/Openai.py +243 -243
- webscout/Provider/PI.py +405 -405
- webscout/Provider/Perplexitylabs.py +430 -430
- webscout/Provider/QwenLM.py +272 -272
- webscout/Provider/STT/__init__.py +16 -1
- webscout/Provider/Sambanova.py +257 -257
- webscout/Provider/StandardInput.py +309 -309
- webscout/Provider/TTI/README.md +82 -82
- webscout/Provider/TTI/__init__.py +33 -18
- webscout/Provider/TTI/aiarta.py +413 -413
- webscout/Provider/TTI/base.py +136 -136
- webscout/Provider/TTI/bing.py +243 -243
- webscout/Provider/TTI/gpt1image.py +149 -149
- webscout/Provider/TTI/imagen.py +196 -196
- webscout/Provider/TTI/infip.py +211 -211
- webscout/Provider/TTI/magicstudio.py +232 -232
- webscout/Provider/TTI/monochat.py +219 -219
- webscout/Provider/TTI/piclumen.py +214 -214
- webscout/Provider/TTI/pixelmuse.py +232 -232
- webscout/Provider/TTI/pollinations.py +232 -232
- webscout/Provider/TTI/together.py +288 -288
- webscout/Provider/TTI/utils.py +12 -12
- webscout/Provider/TTI/venice.py +367 -367
- webscout/Provider/TTS/README.md +192 -192
- webscout/Provider/TTS/__init__.py +33 -18
- webscout/Provider/TTS/parler.py +110 -110
- webscout/Provider/TTS/streamElements.py +333 -333
- webscout/Provider/TTS/utils.py +280 -280
- webscout/Provider/TeachAnything.py +237 -237
- webscout/Provider/TextPollinationsAI.py +310 -310
- webscout/Provider/TogetherAI.py +356 -356
- webscout/Provider/TwoAI.py +312 -312
- webscout/Provider/TypliAI.py +311 -311
- webscout/Provider/UNFINISHED/ChatHub.py +208 -208
- webscout/Provider/UNFINISHED/ChutesAI.py +313 -313
- webscout/Provider/UNFINISHED/GizAI.py +294 -294
- webscout/Provider/UNFINISHED/Marcus.py +198 -198
- webscout/Provider/UNFINISHED/Qodo.py +477 -477
- webscout/Provider/UNFINISHED/VercelAIGateway.py +338 -338
- webscout/Provider/UNFINISHED/XenAI.py +324 -324
- webscout/Provider/UNFINISHED/Youchat.py +330 -330
- webscout/Provider/UNFINISHED/liner.py +334 -0
- webscout/Provider/UNFINISHED/liner_api_request.py +262 -262
- webscout/Provider/UNFINISHED/puterjs.py +634 -634
- webscout/Provider/UNFINISHED/samurai.py +223 -223
- webscout/Provider/UNFINISHED/test_lmarena.py +119 -119
- webscout/Provider/Venice.py +250 -250
- webscout/Provider/VercelAI.py +256 -256
- webscout/Provider/WiseCat.py +231 -231
- webscout/Provider/WrDoChat.py +366 -366
- webscout/Provider/__init__.py +33 -18
- webscout/Provider/ai4chat.py +174 -174
- webscout/Provider/akashgpt.py +331 -331
- webscout/Provider/cerebras.py +446 -446
- webscout/Provider/chatglm.py +394 -301
- webscout/Provider/cleeai.py +211 -211
- webscout/Provider/elmo.py +282 -282
- webscout/Provider/geminiapi.py +208 -208
- webscout/Provider/granite.py +261 -261
- webscout/Provider/hermes.py +263 -263
- webscout/Provider/julius.py +223 -223
- webscout/Provider/learnfastai.py +309 -309
- webscout/Provider/llama3mitril.py +214 -214
- webscout/Provider/llmchat.py +243 -243
- webscout/Provider/llmchatco.py +290 -290
- webscout/Provider/meta.py +801 -801
- webscout/Provider/oivscode.py +309 -309
- webscout/Provider/scira_chat.py +383 -383
- webscout/Provider/searchchat.py +292 -292
- webscout/Provider/sonus.py +258 -258
- webscout/Provider/toolbaz.py +370 -367
- webscout/Provider/turboseek.py +273 -273
- webscout/Provider/typefully.py +207 -207
- webscout/Provider/yep.py +372 -372
- webscout/__init__.py +27 -31
- webscout/__main__.py +5 -5
- webscout/auth/api_key_manager.py +189 -189
- webscout/auth/config.py +175 -175
- webscout/auth/models.py +185 -185
- webscout/auth/routes.py +663 -664
- webscout/auth/simple_logger.py +236 -236
- webscout/cli.py +523 -523
- webscout/conversation.py +438 -438
- webscout/exceptions.py +361 -361
- webscout/litagent/Readme.md +298 -298
- webscout/litagent/__init__.py +28 -28
- webscout/litagent/agent.py +581 -581
- webscout/litagent/constants.py +59 -59
- webscout/litprinter/__init__.py +58 -58
- webscout/models.py +181 -181
- webscout/optimizers.py +419 -419
- webscout/prompt_manager.py +288 -288
- webscout/sanitize.py +1078 -1078
- webscout/scout/README.md +401 -401
- webscout/scout/__init__.py +8 -8
- webscout/scout/core/__init__.py +6 -6
- webscout/scout/core/crawler.py +297 -297
- webscout/scout/core/scout.py +706 -706
- webscout/scout/core/search_result.py +95 -95
- webscout/scout/core/text_analyzer.py +62 -62
- webscout/scout/core/text_utils.py +277 -277
- webscout/scout/core/web_analyzer.py +51 -51
- webscout/scout/element.py +599 -599
- webscout/scout/parsers/__init__.py +69 -69
- webscout/scout/parsers/html5lib_parser.py +172 -172
- webscout/scout/parsers/html_parser.py +236 -236
- webscout/scout/parsers/lxml_parser.py +178 -178
- webscout/scout/utils.py +37 -37
- webscout/search/__init__.py +51 -0
- webscout/search/base.py +195 -0
- webscout/search/duckduckgo_main.py +54 -0
- webscout/search/engines/__init__.py +48 -0
- webscout/search/engines/bing.py +84 -0
- webscout/search/engines/bing_news.py +52 -0
- webscout/search/engines/brave.py +43 -0
- webscout/search/engines/duckduckgo/__init__.py +25 -0
- webscout/search/engines/duckduckgo/answers.py +78 -0
- webscout/search/engines/duckduckgo/base.py +187 -0
- webscout/search/engines/duckduckgo/images.py +97 -0
- webscout/search/engines/duckduckgo/maps.py +168 -0
- webscout/search/engines/duckduckgo/news.py +68 -0
- webscout/search/engines/duckduckgo/suggestions.py +21 -0
- webscout/search/engines/duckduckgo/text.py +211 -0
- webscout/search/engines/duckduckgo/translate.py +47 -0
- webscout/search/engines/duckduckgo/videos.py +63 -0
- webscout/search/engines/duckduckgo/weather.py +74 -0
- webscout/search/engines/mojeek.py +37 -0
- webscout/search/engines/wikipedia.py +56 -0
- webscout/search/engines/yahoo.py +65 -0
- webscout/search/engines/yahoo_news.py +64 -0
- webscout/search/engines/yandex.py +43 -0
- webscout/search/engines/yep/__init__.py +13 -0
- webscout/search/engines/yep/base.py +32 -0
- webscout/search/engines/yep/images.py +99 -0
- webscout/search/engines/yep/suggestions.py +35 -0
- webscout/search/engines/yep/text.py +114 -0
- webscout/search/http_client.py +156 -0
- webscout/search/results.py +137 -0
- webscout/search/yep_main.py +44 -0
- webscout/swiftcli/Readme.md +323 -323
- webscout/swiftcli/__init__.py +95 -95
- webscout/swiftcli/core/__init__.py +7 -7
- webscout/swiftcli/core/cli.py +308 -308
- webscout/swiftcli/core/context.py +104 -104
- webscout/swiftcli/core/group.py +241 -241
- webscout/swiftcli/decorators/__init__.py +28 -28
- webscout/swiftcli/decorators/command.py +221 -221
- webscout/swiftcli/decorators/options.py +220 -220
- webscout/swiftcli/decorators/output.py +302 -302
- webscout/swiftcli/exceptions.py +21 -21
- webscout/swiftcli/plugins/__init__.py +9 -9
- webscout/swiftcli/plugins/base.py +135 -135
- webscout/swiftcli/plugins/manager.py +269 -269
- webscout/swiftcli/utils/__init__.py +59 -59
- webscout/swiftcli/utils/formatting.py +252 -252
- webscout/swiftcli/utils/parsing.py +267 -267
- webscout/update_checker.py +117 -117
- webscout/version.py +1 -1
- webscout/version.py.bak +2 -0
- webscout/zeroart/README.md +89 -89
- webscout/zeroart/__init__.py +134 -134
- webscout/zeroart/base.py +66 -66
- webscout/zeroart/effects.py +100 -100
- webscout/zeroart/fonts.py +1238 -1238
- {webscout-8.3.7.dist-info → webscout-2025.10.13.dist-info}/METADATA +936 -937
- webscout-2025.10.13.dist-info/RECORD +329 -0
- webscout/Provider/AISEARCH/DeepFind.py +0 -254
- webscout/Provider/OPENAI/Qwen3.py +0 -303
- webscout/Provider/OPENAI/qodo.py +0 -630
- webscout/Provider/OPENAI/xenai.py +0 -514
- webscout/tempid.py +0 -134
- webscout/webscout_search.py +0 -1183
- webscout/webscout_search_async.py +0 -649
- webscout/yep_search.py +0 -346
- webscout-8.3.7.dist-info/RECORD +0 -301
- {webscout-8.3.7.dist-info → webscout-2025.10.13.dist-info}/WHEEL +0 -0
- {webscout-8.3.7.dist-info → webscout-2025.10.13.dist-info}/entry_points.txt +0 -0
- {webscout-8.3.7.dist-info → webscout-2025.10.13.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.3.7.dist-info → webscout-2025.10.13.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""HTTP client for search engines."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from random import choice
|
|
7
|
+
from typing import Any, Literal
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
import trio # noqa: F401
|
|
11
|
+
except ImportError:
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
import curl_cffi.requests
|
|
15
|
+
|
|
16
|
+
from ..exceptions import RatelimitE, TimeoutE, WebscoutE
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class HttpClient:
|
|
22
|
+
"""HTTP client wrapper for search engines."""
|
|
23
|
+
|
|
24
|
+
# curl_cffi supported browser impersonations
|
|
25
|
+
_impersonates = (
|
|
26
|
+
"chrome99", "chrome100", "chrome101", "chrome104", "chrome107", "chrome110",
|
|
27
|
+
"chrome116", "chrome119", "chrome120", "chrome123", "chrome124", "chrome131", "chrome133a",
|
|
28
|
+
"chrome99_android", "chrome131_android",
|
|
29
|
+
"safari15_3", "safari15_5", "safari17_0", "safari17_2_ios", "safari18_0", "safari18_0_ios",
|
|
30
|
+
"edge99", "edge101",
|
|
31
|
+
"firefox133", "firefox135",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
proxy: str | None = None,
|
|
37
|
+
timeout: int | None = 10,
|
|
38
|
+
verify: bool = True,
|
|
39
|
+
headers: dict[str, str] | None = None,
|
|
40
|
+
) -> None:
|
|
41
|
+
"""Initialize HTTP client.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
proxy: Proxy URL (supports http/https/socks5).
|
|
45
|
+
timeout: Request timeout in seconds.
|
|
46
|
+
verify: Whether to verify SSL certificates.
|
|
47
|
+
headers: Default headers for requests.
|
|
48
|
+
"""
|
|
49
|
+
self.proxy = proxy
|
|
50
|
+
self.timeout = timeout
|
|
51
|
+
self.verify = verify
|
|
52
|
+
|
|
53
|
+
# Choose random browser to impersonate
|
|
54
|
+
impersonate_browser = choice(self._impersonates)
|
|
55
|
+
|
|
56
|
+
# Initialize curl_cffi session
|
|
57
|
+
self.client = curl_cffi.requests.Session(
|
|
58
|
+
headers=headers or {},
|
|
59
|
+
proxies={'http': self.proxy, 'https': self.proxy} if self.proxy else None,
|
|
60
|
+
timeout=timeout,
|
|
61
|
+
impersonate=impersonate_browser,
|
|
62
|
+
verify=verify,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def request(
|
|
66
|
+
self,
|
|
67
|
+
method: Literal["GET", "POST", "HEAD", "OPTIONS", "DELETE", "PUT", "PATCH"],
|
|
68
|
+
url: str,
|
|
69
|
+
params: dict[str, Any] | None = None,
|
|
70
|
+
data: dict[str, Any] | bytes | None = None,
|
|
71
|
+
json: Any = None,
|
|
72
|
+
headers: dict[str, str] | None = None,
|
|
73
|
+
cookies: dict[str, str] | None = None,
|
|
74
|
+
timeout: int | None = None,
|
|
75
|
+
**kwargs: Any,
|
|
76
|
+
) -> curl_cffi.requests.Response:
|
|
77
|
+
"""Make HTTP request.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
method: HTTP method.
|
|
81
|
+
url: Request URL.
|
|
82
|
+
params: URL parameters.
|
|
83
|
+
data: Request body data.
|
|
84
|
+
json: JSON data to send.
|
|
85
|
+
headers: Request headers.
|
|
86
|
+
cookies: Request cookies.
|
|
87
|
+
timeout: Request timeout (overrides default).
|
|
88
|
+
**kwargs: Additional arguments passed to curl_cffi.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
Response object.
|
|
92
|
+
|
|
93
|
+
Raises:
|
|
94
|
+
TimeoutE: Request timeout.
|
|
95
|
+
RatelimitE: Rate limit exceeded.
|
|
96
|
+
WebscoutE: Other request errors.
|
|
97
|
+
"""
|
|
98
|
+
try:
|
|
99
|
+
request_kwargs: dict[str, Any] = {
|
|
100
|
+
"params": params,
|
|
101
|
+
"headers": headers,
|
|
102
|
+
"json": json,
|
|
103
|
+
"timeout": timeout or self.timeout,
|
|
104
|
+
**kwargs,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if isinstance(cookies, dict):
|
|
108
|
+
request_kwargs["cookies"] = cookies
|
|
109
|
+
|
|
110
|
+
if data is not None:
|
|
111
|
+
request_kwargs["data"] = data
|
|
112
|
+
|
|
113
|
+
resp = self.client.request(method, url, **request_kwargs)
|
|
114
|
+
|
|
115
|
+
# Check response status
|
|
116
|
+
if resp.status_code == 200:
|
|
117
|
+
return resp
|
|
118
|
+
elif resp.status_code in (202, 301, 403, 400, 429, 418):
|
|
119
|
+
raise RatelimitE(f"{resp.url} {resp.status_code} Rate limit")
|
|
120
|
+
else:
|
|
121
|
+
raise WebscoutE(f"{resp.url} returned {resp.status_code}")
|
|
122
|
+
|
|
123
|
+
except curl_cffi.requests.RequestException as ex:
|
|
124
|
+
if "time" in str(ex).lower() or "timeout" in str(ex).lower():
|
|
125
|
+
raise TimeoutE(f"{url} {type(ex).__name__}: {ex}") from ex
|
|
126
|
+
raise WebscoutE(f"{url} {type(ex).__name__}: {ex}") from ex
|
|
127
|
+
|
|
128
|
+
def get(self, url: str, **kwargs: Any) -> curl_cffi.requests.Response:
|
|
129
|
+
"""Make GET request."""
|
|
130
|
+
return self.request("GET", url, **kwargs)
|
|
131
|
+
|
|
132
|
+
def post(self, url: str, **kwargs: Any) -> curl_cffi.requests.Response:
|
|
133
|
+
"""Make POST request."""
|
|
134
|
+
return self.request("POST", url, **kwargs)
|
|
135
|
+
|
|
136
|
+
def set_cookies(self, url: str, cookies: dict[str, str]) -> None:
|
|
137
|
+
"""Set cookies for a domain.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
url: URL to set cookies for.
|
|
141
|
+
cookies: Cookie dictionary.
|
|
142
|
+
"""
|
|
143
|
+
self.client.cookies.update(cookies)
|
|
144
|
+
|
|
145
|
+
def close(self) -> None:
|
|
146
|
+
"""Close the HTTP client."""
|
|
147
|
+
if hasattr(self.client, 'close'):
|
|
148
|
+
self.client.close()
|
|
149
|
+
|
|
150
|
+
def __enter__(self) -> HttpClient:
|
|
151
|
+
"""Context manager entry."""
|
|
152
|
+
return self
|
|
153
|
+
|
|
154
|
+
def __exit__(self, *args: Any) -> None:
|
|
155
|
+
"""Context manager exit."""
|
|
156
|
+
self.close()
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""Result models for search engines."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class TextResult:
|
|
11
|
+
"""Text search result."""
|
|
12
|
+
|
|
13
|
+
title: str = ""
|
|
14
|
+
href: str = ""
|
|
15
|
+
body: str = ""
|
|
16
|
+
|
|
17
|
+
def to_dict(self) -> dict[str, Any]:
|
|
18
|
+
"""Convert to dictionary."""
|
|
19
|
+
return {
|
|
20
|
+
"title": self.title,
|
|
21
|
+
"href": self.href,
|
|
22
|
+
"body": self.body,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class ImagesResult:
|
|
28
|
+
"""Images search result."""
|
|
29
|
+
|
|
30
|
+
title: str = ""
|
|
31
|
+
image: str = ""
|
|
32
|
+
thumbnail: str = ""
|
|
33
|
+
url: str = ""
|
|
34
|
+
height: int = 0
|
|
35
|
+
width: int = 0
|
|
36
|
+
source: str = ""
|
|
37
|
+
|
|
38
|
+
def to_dict(self) -> dict[str, Any]:
|
|
39
|
+
"""Convert to dictionary."""
|
|
40
|
+
return {
|
|
41
|
+
"title": self.title,
|
|
42
|
+
"image": self.image,
|
|
43
|
+
"thumbnail": self.thumbnail,
|
|
44
|
+
"url": self.url,
|
|
45
|
+
"height": self.height,
|
|
46
|
+
"width": self.width,
|
|
47
|
+
"source": self.source,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class VideosResult:
|
|
53
|
+
"""Videos search result."""
|
|
54
|
+
|
|
55
|
+
content: str = ""
|
|
56
|
+
description: str = ""
|
|
57
|
+
duration: str = ""
|
|
58
|
+
embed_html: str = ""
|
|
59
|
+
embed_url: str = ""
|
|
60
|
+
image_token: str = ""
|
|
61
|
+
images: dict[str, str] = field(default_factory=dict)
|
|
62
|
+
provider: str = ""
|
|
63
|
+
published: str = ""
|
|
64
|
+
publisher: str = ""
|
|
65
|
+
statistics: dict[str, int] = field(default_factory=dict)
|
|
66
|
+
title: str = ""
|
|
67
|
+
uploader: str = ""
|
|
68
|
+
|
|
69
|
+
def to_dict(self) -> dict[str, Any]:
|
|
70
|
+
"""Convert to dictionary."""
|
|
71
|
+
return {
|
|
72
|
+
"content": self.content,
|
|
73
|
+
"description": self.description,
|
|
74
|
+
"duration": self.duration,
|
|
75
|
+
"embed_html": self.embed_html,
|
|
76
|
+
"embed_url": self.embed_url,
|
|
77
|
+
"image_token": self.image_token,
|
|
78
|
+
"images": self.images,
|
|
79
|
+
"provider": self.provider,
|
|
80
|
+
"published": self.published,
|
|
81
|
+
"publisher": self.publisher,
|
|
82
|
+
"statistics": self.statistics,
|
|
83
|
+
"title": self.title,
|
|
84
|
+
"uploader": self.uploader,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@dataclass
|
|
89
|
+
class NewsResult:
|
|
90
|
+
"""News search result."""
|
|
91
|
+
|
|
92
|
+
date: str = ""
|
|
93
|
+
title: str = ""
|
|
94
|
+
body: str = ""
|
|
95
|
+
url: str = ""
|
|
96
|
+
image: str = ""
|
|
97
|
+
source: str = ""
|
|
98
|
+
|
|
99
|
+
def to_dict(self) -> dict[str, Any]:
|
|
100
|
+
"""Convert to dictionary."""
|
|
101
|
+
return {
|
|
102
|
+
"date": self.date,
|
|
103
|
+
"title": self.title,
|
|
104
|
+
"body": self.body,
|
|
105
|
+
"url": self.url,
|
|
106
|
+
"image": self.image,
|
|
107
|
+
"source": self.source,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@dataclass
|
|
112
|
+
class BooksResult:
|
|
113
|
+
"""Books search result."""
|
|
114
|
+
|
|
115
|
+
title: str = ""
|
|
116
|
+
author: str = ""
|
|
117
|
+
href: str = ""
|
|
118
|
+
thumbnail: str = ""
|
|
119
|
+
year: str = ""
|
|
120
|
+
publisher: str = ""
|
|
121
|
+
language: str = ""
|
|
122
|
+
filesize: str = ""
|
|
123
|
+
extension: str = ""
|
|
124
|
+
|
|
125
|
+
def to_dict(self) -> dict[str, Any]:
|
|
126
|
+
"""Convert to dictionary."""
|
|
127
|
+
return {
|
|
128
|
+
"title": self.title,
|
|
129
|
+
"author": self.author,
|
|
130
|
+
"href": self.href,
|
|
131
|
+
"thumbnail": self.thumbnail,
|
|
132
|
+
"year": self.year,
|
|
133
|
+
"publisher": self.publisher,
|
|
134
|
+
"language": self.language,
|
|
135
|
+
"filesize": self.filesize,
|
|
136
|
+
"extension": self.extension,
|
|
137
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Yep unified search interface."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import Dict, List, Optional
|
|
5
|
+
from .base import BaseSearch
|
|
6
|
+
from .engines.yep.text import YepSearch as YepTextSearch
|
|
7
|
+
from .engines.yep.images import YepImages
|
|
8
|
+
from .engines.yep.suggestions import YepSuggestions
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class YepSearch(BaseSearch):
|
|
12
|
+
"""Unified Yep search interface."""
|
|
13
|
+
|
|
14
|
+
def text(self, keywords: str, region: str = "all", safesearch: str = "moderate", max_results: Optional[int] = None) -> List[Dict[str, str]]:
|
|
15
|
+
search = YepTextSearch()
|
|
16
|
+
return search.run(keywords, region, safesearch, max_results)
|
|
17
|
+
|
|
18
|
+
def images(self, keywords: str, region: str = "all", safesearch: str = "moderate", max_results: Optional[int] = None) -> List[Dict[str, str]]:
|
|
19
|
+
search = YepImages()
|
|
20
|
+
return search.run(keywords, region, safesearch, max_results)
|
|
21
|
+
|
|
22
|
+
def suggestions(self, keywords: str, region: str = "all") -> List[str]:
|
|
23
|
+
search = YepSuggestions()
|
|
24
|
+
return search.run(keywords, region)
|
|
25
|
+
|
|
26
|
+
def videos(self, *args, **kwargs) -> List[Dict[str, str]]:
|
|
27
|
+
"""Videos search not supported by Yep."""
|
|
28
|
+
raise NotImplementedError("Yep does not support video search")
|
|
29
|
+
|
|
30
|
+
def news(self, *args, **kwargs) -> List[Dict[str, str]]:
|
|
31
|
+
"""News search not supported by Yep."""
|
|
32
|
+
raise NotImplementedError("Yep does not support news search")
|
|
33
|
+
|
|
34
|
+
def answers(self, *args, **kwargs) -> List[Dict[str, str]]:
|
|
35
|
+
"""Instant answers not supported by Yep."""
|
|
36
|
+
raise NotImplementedError("Yep does not support instant answers")
|
|
37
|
+
|
|
38
|
+
def maps(self, *args, **kwargs) -> List[Dict[str, str]]:
|
|
39
|
+
"""Maps search not supported by Yep."""
|
|
40
|
+
raise NotImplementedError("Yep does not support maps search")
|
|
41
|
+
|
|
42
|
+
def translate(self, *args, **kwargs) -> List[Dict[str, str]]:
|
|
43
|
+
"""Translation not supported by Yep."""
|
|
44
|
+
raise NotImplementedError("Yep does not support translation")
|