webscout 8.2.7__py3-none-any.whl → 8.2.8__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 +1 -1
- webscout/AIutel.py +298 -249
- webscout/Extra/Act.md +309 -0
- webscout/Extra/GitToolkit/__init__.py +10 -0
- webscout/Extra/GitToolkit/gitapi/README.md +110 -0
- webscout/Extra/GitToolkit/gitapi/__init__.py +12 -0
- webscout/Extra/GitToolkit/gitapi/repository.py +195 -0
- webscout/Extra/GitToolkit/gitapi/user.py +96 -0
- webscout/Extra/GitToolkit/gitapi/utils.py +62 -0
- webscout/Extra/YTToolkit/README.md +375 -0
- webscout/Extra/YTToolkit/YTdownloader.py +957 -0
- webscout/Extra/YTToolkit/__init__.py +3 -0
- webscout/Extra/YTToolkit/transcriber.py +476 -0
- webscout/Extra/YTToolkit/ytapi/README.md +44 -0
- webscout/Extra/YTToolkit/ytapi/__init__.py +6 -0
- webscout/Extra/YTToolkit/ytapi/channel.py +307 -0
- webscout/Extra/YTToolkit/ytapi/errors.py +13 -0
- webscout/Extra/YTToolkit/ytapi/extras.py +118 -0
- webscout/Extra/YTToolkit/ytapi/https.py +88 -0
- webscout/Extra/YTToolkit/ytapi/patterns.py +61 -0
- webscout/Extra/YTToolkit/ytapi/playlist.py +59 -0
- webscout/Extra/YTToolkit/ytapi/pool.py +8 -0
- webscout/Extra/YTToolkit/ytapi/query.py +40 -0
- webscout/Extra/YTToolkit/ytapi/stream.py +63 -0
- webscout/Extra/YTToolkit/ytapi/utils.py +62 -0
- webscout/Extra/YTToolkit/ytapi/video.py +232 -0
- webscout/Extra/__init__.py +7 -0
- webscout/Extra/autocoder/__init__.py +9 -0
- webscout/Extra/autocoder/autocoder.py +1105 -0
- webscout/Extra/autocoder/autocoder_utiles.py +332 -0
- webscout/Extra/gguf.md +430 -0
- webscout/Extra/gguf.py +684 -0
- webscout/Extra/tempmail/README.md +488 -0
- webscout/Extra/tempmail/__init__.py +28 -0
- webscout/Extra/tempmail/async_utils.py +141 -0
- webscout/Extra/tempmail/base.py +161 -0
- webscout/Extra/tempmail/cli.py +187 -0
- webscout/Extra/tempmail/emailnator.py +84 -0
- webscout/Extra/tempmail/mail_tm.py +361 -0
- webscout/Extra/tempmail/temp_mail_io.py +292 -0
- webscout/Extra/weather.md +281 -0
- webscout/Extra/weather.py +194 -0
- webscout/Extra/weather_ascii.py +76 -0
- webscout/Litlogger/Readme.md +175 -0
- webscout/Litlogger/__init__.py +67 -0
- webscout/Litlogger/core/__init__.py +6 -0
- webscout/Litlogger/core/level.py +23 -0
- webscout/Litlogger/core/logger.py +165 -0
- webscout/Litlogger/handlers/__init__.py +12 -0
- webscout/Litlogger/handlers/console.py +33 -0
- webscout/Litlogger/handlers/file.py +143 -0
- webscout/Litlogger/handlers/network.py +173 -0
- webscout/Litlogger/styles/__init__.py +7 -0
- webscout/Litlogger/styles/colors.py +249 -0
- webscout/Litlogger/styles/formats.py +458 -0
- webscout/Litlogger/styles/text.py +87 -0
- webscout/Litlogger/utils/__init__.py +6 -0
- webscout/Litlogger/utils/detectors.py +153 -0
- webscout/Litlogger/utils/formatters.py +200 -0
- webscout/Provider/AI21.py +177 -0
- webscout/Provider/AISEARCH/DeepFind.py +254 -0
- webscout/Provider/AISEARCH/Perplexity.py +359 -0
- webscout/Provider/AISEARCH/README.md +279 -0
- webscout/Provider/AISEARCH/__init__.py +9 -0
- webscout/Provider/AISEARCH/felo_search.py +228 -0
- webscout/Provider/AISEARCH/genspark_search.py +350 -0
- webscout/Provider/AISEARCH/hika_search.py +198 -0
- webscout/Provider/AISEARCH/iask_search.py +436 -0
- webscout/Provider/AISEARCH/monica_search.py +246 -0
- webscout/Provider/AISEARCH/scira_search.py +324 -0
- webscout/Provider/AISEARCH/webpilotai_search.py +281 -0
- webscout/Provider/Aitopia.py +316 -0
- webscout/Provider/AllenAI.py +440 -0
- webscout/Provider/Andi.py +228 -0
- webscout/Provider/Blackboxai.py +673 -0
- webscout/Provider/ChatGPTClone.py +237 -0
- webscout/Provider/ChatGPTGratis.py +194 -0
- webscout/Provider/ChatSandbox.py +342 -0
- webscout/Provider/Cloudflare.py +324 -0
- webscout/Provider/Cohere.py +208 -0
- webscout/Provider/Deepinfra.py +340 -0
- webscout/Provider/ExaAI.py +261 -0
- webscout/Provider/ExaChat.py +358 -0
- webscout/Provider/Flowith.py +217 -0
- webscout/Provider/FreeGemini.py +250 -0
- webscout/Provider/Gemini.py +169 -0
- webscout/Provider/GithubChat.py +370 -0
- webscout/Provider/GizAI.py +295 -0
- webscout/Provider/Glider.py +225 -0
- webscout/Provider/Groq.py +801 -0
- webscout/Provider/HF_space/__init__.py +0 -0
- webscout/Provider/HF_space/qwen_qwen2.py +206 -0
- webscout/Provider/HeckAI.py +285 -0
- webscout/Provider/HuggingFaceChat.py +469 -0
- webscout/Provider/Hunyuan.py +283 -0
- webscout/Provider/Jadve.py +291 -0
- webscout/Provider/Koboldai.py +384 -0
- webscout/Provider/LambdaChat.py +411 -0
- webscout/Provider/Llama3.py +259 -0
- webscout/Provider/MCPCore.py +315 -0
- webscout/Provider/Marcus.py +198 -0
- webscout/Provider/Nemotron.py +218 -0
- webscout/Provider/Netwrck.py +270 -0
- webscout/Provider/OLLAMA.py +396 -0
- webscout/Provider/OPENAI/BLACKBOXAI.py +735 -0
- webscout/Provider/OPENAI/Cloudflare.py +378 -0
- webscout/Provider/OPENAI/FreeGemini.py +282 -0
- webscout/Provider/OPENAI/NEMOTRON.py +244 -0
- webscout/Provider/OPENAI/README.md +1253 -0
- webscout/Provider/OPENAI/__init__.py +36 -0
- webscout/Provider/OPENAI/ai4chat.py +293 -0
- webscout/Provider/OPENAI/api.py +810 -0
- webscout/Provider/OPENAI/base.py +249 -0
- webscout/Provider/OPENAI/c4ai.py +373 -0
- webscout/Provider/OPENAI/chatgpt.py +556 -0
- webscout/Provider/OPENAI/chatgptclone.py +488 -0
- webscout/Provider/OPENAI/chatsandbox.py +172 -0
- webscout/Provider/OPENAI/deepinfra.py +319 -0
- webscout/Provider/OPENAI/e2b.py +1356 -0
- webscout/Provider/OPENAI/exaai.py +411 -0
- webscout/Provider/OPENAI/exachat.py +443 -0
- webscout/Provider/OPENAI/flowith.py +162 -0
- webscout/Provider/OPENAI/freeaichat.py +359 -0
- webscout/Provider/OPENAI/glider.py +323 -0
- webscout/Provider/OPENAI/groq.py +361 -0
- webscout/Provider/OPENAI/heckai.py +307 -0
- webscout/Provider/OPENAI/llmchatco.py +335 -0
- webscout/Provider/OPENAI/mcpcore.py +383 -0
- webscout/Provider/OPENAI/multichat.py +376 -0
- webscout/Provider/OPENAI/netwrck.py +356 -0
- webscout/Provider/OPENAI/opkfc.py +496 -0
- webscout/Provider/OPENAI/scirachat.py +471 -0
- webscout/Provider/OPENAI/sonus.py +303 -0
- webscout/Provider/OPENAI/standardinput.py +433 -0
- webscout/Provider/OPENAI/textpollinations.py +339 -0
- webscout/Provider/OPENAI/toolbaz.py +413 -0
- webscout/Provider/OPENAI/typefully.py +355 -0
- webscout/Provider/OPENAI/typegpt.py +358 -0
- webscout/Provider/OPENAI/uncovrAI.py +462 -0
- webscout/Provider/OPENAI/utils.py +307 -0
- webscout/Provider/OPENAI/venice.py +425 -0
- webscout/Provider/OPENAI/wisecat.py +381 -0
- webscout/Provider/OPENAI/writecream.py +163 -0
- webscout/Provider/OPENAI/x0gpt.py +378 -0
- webscout/Provider/OPENAI/yep.py +356 -0
- webscout/Provider/OpenGPT.py +209 -0
- webscout/Provider/Openai.py +496 -0
- webscout/Provider/PI.py +429 -0
- webscout/Provider/Perplexitylabs.py +415 -0
- webscout/Provider/QwenLM.py +254 -0
- webscout/Provider/Reka.py +214 -0
- webscout/Provider/StandardInput.py +290 -0
- webscout/Provider/TTI/AiForce/README.md +159 -0
- webscout/Provider/TTI/AiForce/__init__.py +22 -0
- webscout/Provider/TTI/AiForce/async_aiforce.py +224 -0
- webscout/Provider/TTI/AiForce/sync_aiforce.py +245 -0
- webscout/Provider/TTI/FreeAIPlayground/README.md +99 -0
- webscout/Provider/TTI/FreeAIPlayground/__init__.py +9 -0
- webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +181 -0
- webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +180 -0
- webscout/Provider/TTI/ImgSys/README.md +174 -0
- webscout/Provider/TTI/ImgSys/__init__.py +23 -0
- webscout/Provider/TTI/ImgSys/async_imgsys.py +202 -0
- webscout/Provider/TTI/ImgSys/sync_imgsys.py +195 -0
- webscout/Provider/TTI/MagicStudio/README.md +101 -0
- webscout/Provider/TTI/MagicStudio/__init__.py +2 -0
- webscout/Provider/TTI/MagicStudio/async_magicstudio.py +111 -0
- webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +109 -0
- webscout/Provider/TTI/Nexra/README.md +155 -0
- webscout/Provider/TTI/Nexra/__init__.py +22 -0
- webscout/Provider/TTI/Nexra/async_nexra.py +286 -0
- webscout/Provider/TTI/Nexra/sync_nexra.py +258 -0
- webscout/Provider/TTI/PollinationsAI/README.md +146 -0
- webscout/Provider/TTI/PollinationsAI/__init__.py +23 -0
- webscout/Provider/TTI/PollinationsAI/async_pollinations.py +311 -0
- webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +265 -0
- webscout/Provider/TTI/README.md +128 -0
- webscout/Provider/TTI/__init__.py +12 -0
- webscout/Provider/TTI/aiarta/README.md +134 -0
- webscout/Provider/TTI/aiarta/__init__.py +2 -0
- webscout/Provider/TTI/aiarta/async_aiarta.py +482 -0
- webscout/Provider/TTI/aiarta/sync_aiarta.py +440 -0
- webscout/Provider/TTI/artbit/README.md +100 -0
- webscout/Provider/TTI/artbit/__init__.py +22 -0
- webscout/Provider/TTI/artbit/async_artbit.py +155 -0
- webscout/Provider/TTI/artbit/sync_artbit.py +148 -0
- webscout/Provider/TTI/fastflux/README.md +129 -0
- webscout/Provider/TTI/fastflux/__init__.py +22 -0
- webscout/Provider/TTI/fastflux/async_fastflux.py +261 -0
- webscout/Provider/TTI/fastflux/sync_fastflux.py +252 -0
- webscout/Provider/TTI/huggingface/README.md +114 -0
- webscout/Provider/TTI/huggingface/__init__.py +22 -0
- webscout/Provider/TTI/huggingface/async_huggingface.py +199 -0
- webscout/Provider/TTI/huggingface/sync_huggingface.py +195 -0
- webscout/Provider/TTI/piclumen/README.md +161 -0
- webscout/Provider/TTI/piclumen/__init__.py +23 -0
- webscout/Provider/TTI/piclumen/async_piclumen.py +268 -0
- webscout/Provider/TTI/piclumen/sync_piclumen.py +233 -0
- webscout/Provider/TTI/pixelmuse/README.md +79 -0
- webscout/Provider/TTI/pixelmuse/__init__.py +4 -0
- webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +249 -0
- webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +182 -0
- webscout/Provider/TTI/talkai/README.md +139 -0
- webscout/Provider/TTI/talkai/__init__.py +4 -0
- webscout/Provider/TTI/talkai/async_talkai.py +229 -0
- webscout/Provider/TTI/talkai/sync_talkai.py +207 -0
- webscout/Provider/TTS/README.md +192 -0
- webscout/Provider/TTS/__init__.py +9 -0
- webscout/Provider/TTS/base.py +159 -0
- webscout/Provider/TTS/deepgram.py +156 -0
- webscout/Provider/TTS/elevenlabs.py +111 -0
- webscout/Provider/TTS/gesserit.py +128 -0
- webscout/Provider/TTS/murfai.py +113 -0
- webscout/Provider/TTS/parler.py +111 -0
- webscout/Provider/TTS/speechma.py +580 -0
- webscout/Provider/TTS/sthir.py +94 -0
- webscout/Provider/TTS/streamElements.py +333 -0
- webscout/Provider/TTS/utils.py +280 -0
- webscout/Provider/TeachAnything.py +229 -0
- webscout/Provider/TextPollinationsAI.py +308 -0
- webscout/Provider/TwoAI.py +280 -0
- webscout/Provider/TypliAI.py +305 -0
- webscout/Provider/UNFINISHED/ChatHub.py +209 -0
- webscout/Provider/UNFINISHED/Youchat.py +330 -0
- webscout/Provider/UNFINISHED/liner_api_request.py +263 -0
- webscout/Provider/UNFINISHED/oivscode.py +351 -0
- webscout/Provider/UNFINISHED/test_lmarena.py +119 -0
- webscout/Provider/Venice.py +258 -0
- webscout/Provider/VercelAI.py +253 -0
- webscout/Provider/WiseCat.py +233 -0
- webscout/Provider/WrDoChat.py +370 -0
- webscout/Provider/Writecream.py +246 -0
- webscout/Provider/WritingMate.py +269 -0
- webscout/Provider/__init__.py +172 -0
- webscout/Provider/ai4chat.py +149 -0
- webscout/Provider/akashgpt.py +335 -0
- webscout/Provider/asksteve.py +220 -0
- webscout/Provider/cerebras.py +290 -0
- webscout/Provider/chatglm.py +215 -0
- webscout/Provider/cleeai.py +213 -0
- webscout/Provider/copilot.py +425 -0
- webscout/Provider/elmo.py +283 -0
- webscout/Provider/freeaichat.py +285 -0
- webscout/Provider/geminiapi.py +208 -0
- webscout/Provider/granite.py +235 -0
- webscout/Provider/hermes.py +266 -0
- webscout/Provider/julius.py +223 -0
- webscout/Provider/koala.py +170 -0
- webscout/Provider/learnfastai.py +325 -0
- webscout/Provider/llama3mitril.py +215 -0
- webscout/Provider/llmchat.py +258 -0
- webscout/Provider/llmchatco.py +306 -0
- webscout/Provider/lmarena.py +198 -0
- webscout/Provider/meta.py +801 -0
- webscout/Provider/multichat.py +364 -0
- webscout/Provider/samurai.py +223 -0
- webscout/Provider/scira_chat.py +299 -0
- webscout/Provider/scnet.py +243 -0
- webscout/Provider/searchchat.py +292 -0
- webscout/Provider/sonus.py +258 -0
- webscout/Provider/talkai.py +194 -0
- webscout/Provider/toolbaz.py +353 -0
- webscout/Provider/turboseek.py +266 -0
- webscout/Provider/typefully.py +202 -0
- webscout/Provider/typegpt.py +289 -0
- webscout/Provider/uncovr.py +368 -0
- webscout/Provider/x0gpt.py +299 -0
- webscout/Provider/yep.py +389 -0
- webscout/__init__.py +4 -2
- webscout/cli.py +3 -28
- webscout/conversation.py +35 -35
- webscout/litagent/Readme.md +276 -0
- webscout/litagent/__init__.py +29 -0
- webscout/litagent/agent.py +455 -0
- webscout/litagent/constants.py +60 -0
- webscout/litprinter/__init__.py +59 -0
- webscout/scout/README.md +402 -0
- webscout/scout/__init__.py +8 -0
- webscout/scout/core/__init__.py +7 -0
- webscout/scout/core/crawler.py +140 -0
- webscout/scout/core/scout.py +568 -0
- webscout/scout/core/search_result.py +96 -0
- webscout/scout/core/text_analyzer.py +63 -0
- webscout/scout/core/text_utils.py +277 -0
- webscout/scout/core/web_analyzer.py +52 -0
- webscout/scout/element.py +460 -0
- webscout/scout/parsers/__init__.py +69 -0
- webscout/scout/parsers/html5lib_parser.py +172 -0
- webscout/scout/parsers/html_parser.py +236 -0
- webscout/scout/parsers/lxml_parser.py +178 -0
- webscout/scout/utils.py +37 -0
- webscout/swiftcli/Readme.md +323 -0
- webscout/swiftcli/__init__.py +95 -0
- webscout/swiftcli/core/__init__.py +7 -0
- webscout/swiftcli/core/cli.py +297 -0
- webscout/swiftcli/core/context.py +104 -0
- webscout/swiftcli/core/group.py +241 -0
- webscout/swiftcli/decorators/__init__.py +28 -0
- webscout/swiftcli/decorators/command.py +221 -0
- webscout/swiftcli/decorators/options.py +220 -0
- webscout/swiftcli/decorators/output.py +252 -0
- webscout/swiftcli/exceptions.py +21 -0
- webscout/swiftcli/plugins/__init__.py +9 -0
- webscout/swiftcli/plugins/base.py +135 -0
- webscout/swiftcli/plugins/manager.py +262 -0
- webscout/swiftcli/utils/__init__.py +59 -0
- webscout/swiftcli/utils/formatting.py +252 -0
- webscout/swiftcli/utils/parsing.py +267 -0
- webscout/version.py +1 -1
- webscout/webscout_search.py +2 -182
- webscout/webscout_search_async.py +1 -179
- webscout/zeroart/README.md +89 -0
- webscout/zeroart/__init__.py +135 -0
- webscout/zeroart/base.py +66 -0
- webscout/zeroart/effects.py +101 -0
- webscout/zeroart/fonts.py +1239 -0
- {webscout-8.2.7.dist-info → webscout-8.2.8.dist-info}/METADATA +115 -60
- webscout-8.2.8.dist-info/RECORD +334 -0
- {webscout-8.2.7.dist-info → webscout-8.2.8.dist-info}/WHEEL +1 -1
- webscout-8.2.7.dist-info/RECORD +0 -26
- {webscout-8.2.7.dist-info → webscout-8.2.8.dist-info}/entry_points.txt +0 -0
- {webscout-8.2.7.dist-info → webscout-8.2.8.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.2.7.dist-info → webscout-8.2.8.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from typing import List, Dict, Any
|
|
2
|
+
from .utils import request
|
|
3
|
+
|
|
4
|
+
class User:
|
|
5
|
+
"""Class for interacting with GitHub user data"""
|
|
6
|
+
|
|
7
|
+
def __init__(self, username: str):
|
|
8
|
+
"""
|
|
9
|
+
Initialize user client
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
username: GitHub username
|
|
13
|
+
"""
|
|
14
|
+
self.username = username
|
|
15
|
+
self.base_url = f"https://api.github.com/users/{username}"
|
|
16
|
+
|
|
17
|
+
def get_profile(self) -> Dict[str, Any]:
|
|
18
|
+
"""Get user profile information"""
|
|
19
|
+
return request(self.base_url)
|
|
20
|
+
|
|
21
|
+
def get_repositories(self, page: int = 1, per_page: int = 30, type: str = "all") -> List[Dict[str, Any]]:
|
|
22
|
+
"""
|
|
23
|
+
Get user's public repositories
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
page: Page number
|
|
27
|
+
per_page: Items per page
|
|
28
|
+
type: Type of repositories (all/owner/member)
|
|
29
|
+
"""
|
|
30
|
+
url = f"{self.base_url}/repos?page={page}&per_page={per_page}&type={type}"
|
|
31
|
+
return request(url)
|
|
32
|
+
|
|
33
|
+
def get_starred(self, page: int = 1, per_page: int = 30) -> List[Dict[str, Any]]:
|
|
34
|
+
"""Get repositories starred by user"""
|
|
35
|
+
url = f"{self.base_url}/starred?page={page}&per_page={per_page}"
|
|
36
|
+
return request(url)
|
|
37
|
+
|
|
38
|
+
def get_followers(self, page: int = 1, per_page: int = 30) -> List[Dict[str, Any]]:
|
|
39
|
+
"""Get user's followers"""
|
|
40
|
+
url = f"{self.base_url}/followers?page={page}&per_page={per_page}"
|
|
41
|
+
return request(url)
|
|
42
|
+
|
|
43
|
+
def get_following(self, page: int = 1, per_page: int = 30) -> List[Dict[str, Any]]:
|
|
44
|
+
"""Get users followed by this user"""
|
|
45
|
+
url = f"{self.base_url}/following?page={page}&per_page={per_page}"
|
|
46
|
+
return request(url)
|
|
47
|
+
|
|
48
|
+
def get_gists(self, page: int = 1, per_page: int = 30) -> List[Dict[str, Any]]:
|
|
49
|
+
"""Get user's public gists"""
|
|
50
|
+
url = f"{self.base_url}/gists?page={page}&per_page={per_page}"
|
|
51
|
+
return request(url)
|
|
52
|
+
|
|
53
|
+
def get_organizations(self) -> List[Dict[str, Any]]:
|
|
54
|
+
"""Get user's organizations"""
|
|
55
|
+
url = f"{self.base_url}/orgs"
|
|
56
|
+
return request(url)
|
|
57
|
+
|
|
58
|
+
def get_received_events(self, page: int = 1, per_page: int = 30) -> List[Dict[str, Any]]:
|
|
59
|
+
"""Get events received by user"""
|
|
60
|
+
url = f"{self.base_url}/received_events?page={page}&per_page={per_page}"
|
|
61
|
+
return request(url)
|
|
62
|
+
|
|
63
|
+
def get_public_events(self, page: int = 1, per_page: int = 30) -> List[Dict[str, Any]]:
|
|
64
|
+
"""Get user's public events"""
|
|
65
|
+
url = f"{self.base_url}/events/public?page={page}&per_page={per_page}"
|
|
66
|
+
return request(url)
|
|
67
|
+
|
|
68
|
+
def get_starred_gists(self) -> List[Dict[str, Any]]:
|
|
69
|
+
"""Get gists starred by user"""
|
|
70
|
+
url = f"{self.base_url}/starred_gists"
|
|
71
|
+
return request(url)
|
|
72
|
+
|
|
73
|
+
def get_subscriptions(self) -> List[Dict[str, Any]]:
|
|
74
|
+
"""Get repositories user is watching"""
|
|
75
|
+
url = f"{self.base_url}/subscriptions"
|
|
76
|
+
return request(url)
|
|
77
|
+
|
|
78
|
+
def get_hovercard(self) -> Dict[str, Any]:
|
|
79
|
+
"""Get user's hovercard information"""
|
|
80
|
+
url = f"{self.base_url}/hovercard"
|
|
81
|
+
return request(url)
|
|
82
|
+
|
|
83
|
+
def get_installation(self) -> Dict[str, Any]:
|
|
84
|
+
"""Get user's GitHub App installations"""
|
|
85
|
+
url = f"{self.base_url}/installation"
|
|
86
|
+
return request(url)
|
|
87
|
+
|
|
88
|
+
def get_keys(self) -> List[Dict[str, Any]]:
|
|
89
|
+
"""Get user's public SSH keys"""
|
|
90
|
+
url = f"{self.base_url}/keys"
|
|
91
|
+
return request(url)
|
|
92
|
+
|
|
93
|
+
def get_gpg_keys(self) -> List[Dict[str, Any]]:
|
|
94
|
+
"""Get user's public GPG keys"""
|
|
95
|
+
url = f"{self.base_url}/gpg_keys"
|
|
96
|
+
return request(url)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from urllib.request import Request, urlopen
|
|
2
|
+
from urllib.error import HTTPError
|
|
3
|
+
import json
|
|
4
|
+
from typing import Dict, Any
|
|
5
|
+
from webscout.litagent import LitAgent
|
|
6
|
+
|
|
7
|
+
class GitError(Exception):
|
|
8
|
+
"""Base exception for GitHub API errors"""
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
class RateLimitError(GitError):
|
|
12
|
+
"""Raised when hitting GitHub API rate limits"""
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
class NotFoundError(GitError):
|
|
16
|
+
"""Raised when resource is not found"""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
class RequestError(GitError):
|
|
20
|
+
"""Raised for general request errors"""
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
_USER_AGENT_GENERATOR = LitAgent()
|
|
24
|
+
|
|
25
|
+
def request(url: str, retry_attempts: int = 3) -> Dict[str, Any]:
|
|
26
|
+
"""
|
|
27
|
+
Send a request to GitHub API with retry mechanism
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
url: GitHub API endpoint URL
|
|
31
|
+
retry_attempts: Number of retry attempts
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Parsed JSON response
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
NotFoundError: If resource not found
|
|
38
|
+
RateLimitError: If rate limited
|
|
39
|
+
RequestError: For other request errors
|
|
40
|
+
"""
|
|
41
|
+
headers = {
|
|
42
|
+
"User-Agent": _USER_AGENT_GENERATOR.random(),
|
|
43
|
+
"Accept": "application/vnd.github+json"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for attempt in range(retry_attempts):
|
|
47
|
+
try:
|
|
48
|
+
req = Request(url, headers=headers)
|
|
49
|
+
response = urlopen(req)
|
|
50
|
+
return json.loads(response.read().decode('utf-8'))
|
|
51
|
+
|
|
52
|
+
except HTTPError as e:
|
|
53
|
+
if e.code == 404:
|
|
54
|
+
raise NotFoundError(f"Resource not found: {url}")
|
|
55
|
+
if e.code == 429:
|
|
56
|
+
raise RateLimitError(f"Rate limited on attempt {attempt + 1}")
|
|
57
|
+
if attempt == retry_attempts - 1:
|
|
58
|
+
raise RequestError(f"HTTP Error {e.code}: {e.reason}")
|
|
59
|
+
|
|
60
|
+
except Exception as e:
|
|
61
|
+
if attempt == retry_attempts - 1:
|
|
62
|
+
raise RequestError(f"Request failed: {str(e)}")
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://github.com/OEvortex/Webscout">
|
|
3
|
+
<img src="https://img.shields.io/badge/YTToolkit-YouTube%20Toolkit-red?style=for-the-badge&logo=youtube&logoColor=white" alt="YTToolkit Logo">
|
|
4
|
+
</a>
|
|
5
|
+
<h1>YTToolkit</h1>
|
|
6
|
+
<p><strong>Comprehensive YouTube Toolkit for Downloading, Transcription, and Data Extraction</strong></p>
|
|
7
|
+
|
|
8
|
+
<!-- Badges -->
|
|
9
|
+
<p>
|
|
10
|
+
<a href="https://pypi.org/project/webscout/"><img src="https://img.shields.io/pypi/v/webscout.svg?style=flat-square&logo=pypi&label=PyPI" alt="PyPI Version"></a>
|
|
11
|
+
<a href="#"><img src="https://img.shields.io/badge/No%20API%20Key-Required-success?style=flat-square" alt="No API Key Required"></a>
|
|
12
|
+
<a href="#"><img src="https://img.shields.io/badge/Python-3.7%2B-blue?style=flat-square&logo=python" alt="Python Version"></a>
|
|
13
|
+
</p>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
> [!NOTE]
|
|
17
|
+
> YTToolkit provides a complete suite of YouTube tools including video downloading, transcript extraction, and comprehensive data retrieval - all without requiring an official API key.
|
|
18
|
+
|
|
19
|
+
## ✨ Features
|
|
20
|
+
|
|
21
|
+
### Video Management
|
|
22
|
+
|
|
23
|
+
* **Advanced Video Downloading**
|
|
24
|
+
* Multiple format support (MP4, MP3)
|
|
25
|
+
* Customizable quality selection (up to 4K)
|
|
26
|
+
* Progress tracking and auto-save functionality
|
|
27
|
+
* Batch downloading with search capabilities
|
|
28
|
+
|
|
29
|
+
* **Transcript Extraction**
|
|
30
|
+
* Multi-language transcript support
|
|
31
|
+
* Automatic and manual transcript fetching
|
|
32
|
+
* Real-time translation capabilities
|
|
33
|
+
* Flexible parsing options
|
|
34
|
+
|
|
35
|
+
### Data Extraction
|
|
36
|
+
|
|
37
|
+
* **Channel Information**
|
|
38
|
+
* Comprehensive channel metadata
|
|
39
|
+
* Subscriber count, views, and engagement metrics
|
|
40
|
+
* Avatar and banner image URLs
|
|
41
|
+
* Social media links and about information
|
|
42
|
+
|
|
43
|
+
* **Video Intelligence**
|
|
44
|
+
* Detailed video metadata retrieval
|
|
45
|
+
* Thumbnail extraction in multiple resolutions
|
|
46
|
+
* Stream and upload history tracking
|
|
47
|
+
* Embed code generation
|
|
48
|
+
|
|
49
|
+
* **Search & Discovery**
|
|
50
|
+
* Advanced search capabilities
|
|
51
|
+
* Trending videos across categories
|
|
52
|
+
* Playlist content extraction
|
|
53
|
+
* No official API dependency
|
|
54
|
+
|
|
55
|
+
## 🚀 Installation
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install -U webscout
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 💻 Quick Start Guide
|
|
62
|
+
|
|
63
|
+
### Video Downloading
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from webscout import Handler
|
|
67
|
+
|
|
68
|
+
# Basic video download
|
|
69
|
+
downloader = Handler('https://youtube.com/watch?v=dQw4w9WgXcQ')
|
|
70
|
+
downloader.save()
|
|
71
|
+
|
|
72
|
+
# Advanced download with custom settings
|
|
73
|
+
downloader = Handler(
|
|
74
|
+
query='python tutorial', # Search query
|
|
75
|
+
format='mp4', # Format (mp4, mp3)
|
|
76
|
+
quality='720p', # Quality (144p to 4K)
|
|
77
|
+
limit=5 # Number of videos to download
|
|
78
|
+
)
|
|
79
|
+
downloader.auto_save(dir='./downloads')
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Transcript Extraction
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from webscout import YTTranscriber
|
|
86
|
+
|
|
87
|
+
# Get video transcript
|
|
88
|
+
transcript = YTTranscriber.get_transcript('https://youtube.com/watch?v=dQw4w9WgXcQ')
|
|
89
|
+
print(transcript)
|
|
90
|
+
|
|
91
|
+
# Get transcript in a specific language
|
|
92
|
+
spanish_transcript = YTTranscriber.get_transcript(
|
|
93
|
+
'dQw4w9WgXcQ', # Video ID or URL
|
|
94
|
+
languages='es' # Language code
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Translate transcript
|
|
98
|
+
translated = YTTranscriber.translate_transcript(
|
|
99
|
+
'dQw4w9WgXcQ', # Video ID or URL
|
|
100
|
+
source_lang='en',
|
|
101
|
+
target_lang='fr'
|
|
102
|
+
)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Channel Information
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from webscout import Channel
|
|
109
|
+
|
|
110
|
+
# Create a channel instance
|
|
111
|
+
channel = Channel('@PewDiePie') # Handle, ID, or URL
|
|
112
|
+
|
|
113
|
+
# Access channel metadata
|
|
114
|
+
print(f"Channel: {channel.name}")
|
|
115
|
+
print(f"Subscribers: {channel.subscribers}")
|
|
116
|
+
print(f"Total Views: {channel.views}")
|
|
117
|
+
print(f"Country: {channel.country}")
|
|
118
|
+
|
|
119
|
+
# Get media URLs
|
|
120
|
+
print(f"Avatar: {channel.avatar}")
|
|
121
|
+
print(f"Banner: {channel.banner}")
|
|
122
|
+
|
|
123
|
+
# Get recent uploads
|
|
124
|
+
recent_videos = channel.uploads(10) # 10 most recent videos
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Video Metadata
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from webscout import Video
|
|
131
|
+
|
|
132
|
+
# Get video information
|
|
133
|
+
video = Video('https://www.youtube.com/watch?v=dQw4w9WgXcQ')
|
|
134
|
+
metadata = video.metadata
|
|
135
|
+
|
|
136
|
+
print(f"Title: {metadata['title']}")
|
|
137
|
+
print(f"Views: {metadata['views']}")
|
|
138
|
+
print(f"Duration: {metadata['duration']} seconds")
|
|
139
|
+
print(f"Upload Date: {metadata['upload_date']}")
|
|
140
|
+
|
|
141
|
+
# Get thumbnails
|
|
142
|
+
thumbnails = video.thumbnail_urls
|
|
143
|
+
print(f"Default thumbnail: {thumbnails['default']}")
|
|
144
|
+
print(f"High quality: {thumbnails['high']}")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Search & Trending
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from webscout import Search, Extras
|
|
151
|
+
|
|
152
|
+
# Search for videos
|
|
153
|
+
video_results = Search.videos("Python tutorial", limit=5)
|
|
154
|
+
|
|
155
|
+
# Search for channels
|
|
156
|
+
channel_results = Search.channels("coding", limit=3)
|
|
157
|
+
|
|
158
|
+
# Get trending videos
|
|
159
|
+
trending = Extras.trending_videos(limit=10)
|
|
160
|
+
|
|
161
|
+
# Get category-specific videos
|
|
162
|
+
music_videos = Extras.music_videos(limit=5)
|
|
163
|
+
gaming_videos = Extras.gaming_videos(limit=5)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## 📓 Detailed Documentation
|
|
167
|
+
|
|
168
|
+
<details>
|
|
169
|
+
<summary><strong>Video Downloader (Handler)</strong></summary>
|
|
170
|
+
|
|
171
|
+
The `Handler` class provides powerful video downloading capabilities:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
from webscout import Handler
|
|
175
|
+
|
|
176
|
+
# Initialize with video URL or search query
|
|
177
|
+
downloader = Handler('https://youtube.com/watch?v=dQw4w9WgXcQ')
|
|
178
|
+
|
|
179
|
+
# Basic download with default settings
|
|
180
|
+
downloader.save() # Saves to current directory
|
|
181
|
+
|
|
182
|
+
# Download with custom settings
|
|
183
|
+
downloader.save(
|
|
184
|
+
filename='custom_name', # Custom filename
|
|
185
|
+
format='mp3', # Format (mp4, mp3)
|
|
186
|
+
quality='highest', # Quality setting
|
|
187
|
+
output_path='./videos' # Output directory
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Batch download from search
|
|
191
|
+
batch_downloader = Handler(
|
|
192
|
+
query='python tutorials',
|
|
193
|
+
limit=5, # Number of videos
|
|
194
|
+
format='mp4',
|
|
195
|
+
quality='720p'
|
|
196
|
+
)
|
|
197
|
+
batch_downloader.auto_save()
|
|
198
|
+
|
|
199
|
+
# Get download progress
|
|
200
|
+
progress = downloader.progress
|
|
201
|
+
print(f"Download progress: {progress}%")
|
|
202
|
+
|
|
203
|
+
# Get download history
|
|
204
|
+
history = downloader.history
|
|
205
|
+
print(f"Downloaded files: {history}")
|
|
206
|
+
```
|
|
207
|
+
</details>
|
|
208
|
+
|
|
209
|
+
<details>
|
|
210
|
+
<summary><strong>Transcript Retriever (YTTranscriber)</strong></summary>
|
|
211
|
+
|
|
212
|
+
The `YTTranscriber` class extracts and processes video transcripts:
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
from webscout import YTTranscriber
|
|
216
|
+
|
|
217
|
+
# Get available transcript languages
|
|
218
|
+
languages = YTTranscriber.get_available_languages('dQw4w9WgXcQ')
|
|
219
|
+
print(f"Available languages: {languages}")
|
|
220
|
+
|
|
221
|
+
# Get transcript with specific options
|
|
222
|
+
transcript = YTTranscriber.get_transcript(
|
|
223
|
+
'dQw4w9WgXcQ',
|
|
224
|
+
languages=['en', 'es', 'fr'], # Preferred languages in order
|
|
225
|
+
translate=True, # Auto-translate if needed
|
|
226
|
+
format='text' # Format: 'text', 'json', or 'srt'
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
# Get transcript with timestamps
|
|
230
|
+
timestamped = YTTranscriber.get_transcript(
|
|
231
|
+
'dQw4w9WgXcQ',
|
|
232
|
+
include_timestamps=True
|
|
233
|
+
)
|
|
234
|
+
for entry in timestamped:
|
|
235
|
+
print(f"[{entry['start']:.2f}s] {entry['text']}")
|
|
236
|
+
|
|
237
|
+
# Save transcript to file
|
|
238
|
+
YTTranscriber.save_transcript(
|
|
239
|
+
'dQw4w9WgXcQ',
|
|
240
|
+
output_file='transcript.txt',
|
|
241
|
+
format='text'
|
|
242
|
+
)
|
|
243
|
+
```
|
|
244
|
+
</details>
|
|
245
|
+
|
|
246
|
+
<details>
|
|
247
|
+
<summary><strong>Channel Class</strong></summary>
|
|
248
|
+
|
|
249
|
+
The `Channel` class provides comprehensive access to YouTube channel data:
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
from webscout import Channel
|
|
253
|
+
|
|
254
|
+
# Initialize with channel handle, ID, or URL
|
|
255
|
+
channel = Channel('@PewDiePie')
|
|
256
|
+
|
|
257
|
+
# Basic information
|
|
258
|
+
print(f"Name: {channel.name}")
|
|
259
|
+
print(f"ID: {channel.id}")
|
|
260
|
+
print(f"Subscribers: {channel.subscribers}")
|
|
261
|
+
print(f"Total Views: {channel.views}")
|
|
262
|
+
print(f"Country: {channel.country}")
|
|
263
|
+
|
|
264
|
+
# Media URLs
|
|
265
|
+
print(f"Avatar: {channel.avatar}")
|
|
266
|
+
print(f"Banner: {channel.banner}")
|
|
267
|
+
print(f"URL: {channel.url}")
|
|
268
|
+
|
|
269
|
+
# Content
|
|
270
|
+
print(f"Description: {channel.description}")
|
|
271
|
+
print(f"Social Links: {channel.socials}")
|
|
272
|
+
|
|
273
|
+
# Live status
|
|
274
|
+
if channel.live:
|
|
275
|
+
print(f"Currently streaming: {channel.streaming_now}")
|
|
276
|
+
|
|
277
|
+
# Get videos
|
|
278
|
+
recent_uploads = channel.uploads(20) # Get 20 most recent videos
|
|
279
|
+
```
|
|
280
|
+
</details>
|
|
281
|
+
|
|
282
|
+
<details>
|
|
283
|
+
<summary><strong>Video Class</strong></summary>
|
|
284
|
+
|
|
285
|
+
The `Video` class extracts detailed information about YouTube videos:
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
from webscout import Video
|
|
289
|
+
|
|
290
|
+
# Initialize with video ID or URL
|
|
291
|
+
video = Video('https://www.youtube.com/watch?v=dQw4w9WgXcQ')
|
|
292
|
+
|
|
293
|
+
# Get comprehensive metadata
|
|
294
|
+
metadata = video.metadata
|
|
295
|
+
print(f"Title: {metadata['title']}")
|
|
296
|
+
print(f"Views: {metadata['views']}")
|
|
297
|
+
print(f"Duration: {metadata['duration']} seconds")
|
|
298
|
+
print(f"Upload Date: {metadata['upload_date']}")
|
|
299
|
+
print(f"Author ID: {metadata['author_id']}")
|
|
300
|
+
print(f"Tags: {metadata['tags']}")
|
|
301
|
+
|
|
302
|
+
# Get thumbnails in different resolutions
|
|
303
|
+
thumbnails = video.thumbnail_urls
|
|
304
|
+
print(f"Default thumbnail: {thumbnails['default']}")
|
|
305
|
+
print(f"High quality thumbnail: {thumbnails['high']}")
|
|
306
|
+
print(f"Maximum resolution thumbnail: {thumbnails['maxres']}")
|
|
307
|
+
|
|
308
|
+
# Get embed code and URL
|
|
309
|
+
print(f"Embed HTML: {video.embed_html}")
|
|
310
|
+
print(f"Embed URL: {video.embed_url}")
|
|
311
|
+
```
|
|
312
|
+
</details>
|
|
313
|
+
|
|
314
|
+
<details>
|
|
315
|
+
<summary><strong>Search & Extras Classes</strong></summary>
|
|
316
|
+
|
|
317
|
+
The `Search` and `Extras` classes provide discovery capabilities:
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
from webscout import Search, Extras
|
|
321
|
+
|
|
322
|
+
# Search for videos with advanced options
|
|
323
|
+
video_results = Search.videos(
|
|
324
|
+
"Python tutorial",
|
|
325
|
+
limit=5, # Number of results
|
|
326
|
+
sort_by="relevance", # Sort order
|
|
327
|
+
filter_by="video" # Filter type
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
# Search for channels
|
|
331
|
+
channel_results = Search.channels("coding", limit=3)
|
|
332
|
+
|
|
333
|
+
# Search for playlists
|
|
334
|
+
playlist_results = Search.playlists("music mix", limit=3)
|
|
335
|
+
|
|
336
|
+
# Get trending videos by region
|
|
337
|
+
trending = Extras.trending_videos(
|
|
338
|
+
limit=10,
|
|
339
|
+
region="US" # Country code
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
# Get category-specific videos
|
|
343
|
+
music = Extras.music_videos(limit=5)
|
|
344
|
+
gaming = Extras.gaming_videos(limit=5)
|
|
345
|
+
```
|
|
346
|
+
</details>
|
|
347
|
+
|
|
348
|
+
## 📚 Module Structure
|
|
349
|
+
|
|
350
|
+
| Module | File | Description |
|
|
351
|
+
|--------|------|-------------|
|
|
352
|
+
| **Video Downloader** | [`YTdownloader.py`](YTdownloader.py) | YouTube video downloading with format and quality options |
|
|
353
|
+
| **Transcript Retriever** | [`transcriber.py`](transcriber.py) | Multi-language transcript extraction and translation |
|
|
354
|
+
| **Channel Data** | [`ytapi/channel.py`](ytapi/channel.py) | Channel metadata and interaction |
|
|
355
|
+
| **Video Information** | [`ytapi/video.py`](ytapi/video.py) | Video information extraction |
|
|
356
|
+
| **Search** | [`ytapi/query.py`](ytapi/query.py) | Advanced search capabilities |
|
|
357
|
+
| **Trending** | [`ytapi/extras.py`](ytapi/extras.py) | Trending and category-based video retrieval |
|
|
358
|
+
| **Playlists** | [`ytapi/playlist.py`](ytapi/playlist.py) | Playlist metadata extraction |
|
|
359
|
+
|
|
360
|
+
## ⚠️ Disclaimer
|
|
361
|
+
|
|
362
|
+
> [!WARNING]
|
|
363
|
+
> This toolkit is designed for educational and research purposes only. Please use responsibly and in accordance with YouTube's terms of service. The developers are not responsible for any misuse of this software.
|
|
364
|
+
|
|
365
|
+
## 🤝 Contributing
|
|
366
|
+
|
|
367
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
368
|
+
|
|
369
|
+
<div align="center">
|
|
370
|
+
<p>
|
|
371
|
+
<a href="https://t.me/PyscoutAI"><img alt="Telegram Group" src="https://img.shields.io/badge/Telegram%20Group-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white"></a>
|
|
372
|
+
<a href="https://youtube.com/@OEvortex"><img alt="YouTube" src="https://img.shields.io/badge/YouTube-FF0000?style=for-the-badge&logo=youtube&logoColor=white"></a>
|
|
373
|
+
<a href="https://buymeacoffee.com/oevortex"><img alt="Buy Me A Coffee" src="https://img.shields.io/badge/Buy%20Me%20A%20Coffee-FFDD00?style=for-the-badge&logo=buymeacoffee&logoColor=black"></a>
|
|
374
|
+
</p>
|
|
375
|
+
</div>
|