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,323 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# ⚡ SwiftCLI
|
|
4
|
+
|
|
5
|
+
> Build Beautiful Command-Line Applications at Light Speed
|
|
6
|
+
|
|
7
|
+
[](https://www.python.org)
|
|
8
|
+
[](https://pypi.org/project/webscout/)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
## 🌟 Key Features
|
|
15
|
+
|
|
16
|
+
- 🎨 **Rich Output**: Beautiful tables, progress bars, and styled text
|
|
17
|
+
- 🔄 **Command Groups**: Organize commands logically
|
|
18
|
+
- 🎯 **Type Safety**: Full type hints and runtime validation
|
|
19
|
+
- 🔌 **Plugin System**: Extend functionality easily
|
|
20
|
+
- 🌍 **Environment Support**: Load config from env vars and files
|
|
21
|
+
- 🚀 **Modern Python**: Async support, type hints, and more
|
|
22
|
+
|
|
23
|
+
## 📦 Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install -U webscout
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 🚀 Quick Start
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from webscout.swiftcli import CLI, option, table_output
|
|
33
|
+
|
|
34
|
+
app = CLI("myapp", version="1.0.0")
|
|
35
|
+
|
|
36
|
+
@app.command()
|
|
37
|
+
@option("--count", "-c", type=int, default=5)
|
|
38
|
+
@table_output(["ID", "Status"])
|
|
39
|
+
def list_items(count: int):
|
|
40
|
+
"""List system items with status"""
|
|
41
|
+
return [
|
|
42
|
+
[i, "Active" if i % 2 == 0 else "Inactive"]
|
|
43
|
+
for i in range(1, count + 1)
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
app.run()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Run it:
|
|
51
|
+
```bash
|
|
52
|
+
$ python app.py list-items --count 3
|
|
53
|
+
┌────┬──────────┐
|
|
54
|
+
│ ID │ Status │
|
|
55
|
+
├────┼──────────┤
|
|
56
|
+
│ 1 │ Inactive │
|
|
57
|
+
│ 2 │ Active │
|
|
58
|
+
│ 3 │ Inactive │
|
|
59
|
+
└────┴──────────┘
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 📚 Documentation
|
|
63
|
+
|
|
64
|
+
### Command Groups
|
|
65
|
+
|
|
66
|
+
Organize related commands:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
@app.group()
|
|
70
|
+
def db():
|
|
71
|
+
"""Database operations"""
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
@db.command()
|
|
75
|
+
@option("--force", is_flag=True)
|
|
76
|
+
def migrate(force: bool):
|
|
77
|
+
"""Run database migrations"""
|
|
78
|
+
print(f"Running migrations (force={force})")
|
|
79
|
+
|
|
80
|
+
# Usage: python app.py db migrate --force
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Rich Output
|
|
84
|
+
|
|
85
|
+
Beautiful progress bars and tables:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
@app.command()
|
|
89
|
+
@progress("Processing")
|
|
90
|
+
async def process():
|
|
91
|
+
"""Process items with progress"""
|
|
92
|
+
for i in range(5):
|
|
93
|
+
yield f"Step {i+1}/5"
|
|
94
|
+
await asyncio.sleep(0.5)
|
|
95
|
+
|
|
96
|
+
@app.command()
|
|
97
|
+
@table_output(["Name", "Score"])
|
|
98
|
+
def top_scores():
|
|
99
|
+
"""Show top scores"""
|
|
100
|
+
return [
|
|
101
|
+
["Alice", 100],
|
|
102
|
+
["Bob", 95],
|
|
103
|
+
["Charlie", 90]
|
|
104
|
+
]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Type-Safe Options
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from enum import Enum
|
|
111
|
+
from datetime import datetime
|
|
112
|
+
from typing import List, Optional
|
|
113
|
+
|
|
114
|
+
class Format(Enum):
|
|
115
|
+
JSON = "json"
|
|
116
|
+
YAML = "yaml"
|
|
117
|
+
CSV = "csv"
|
|
118
|
+
|
|
119
|
+
@app.command()
|
|
120
|
+
@option("--format", type=Format, default=Format.JSON)
|
|
121
|
+
@option("--date", type=datetime)
|
|
122
|
+
@option("--tags", type=List[str])
|
|
123
|
+
def export(
|
|
124
|
+
format: Format,
|
|
125
|
+
date: datetime,
|
|
126
|
+
tags: Optional[List[str]] = None
|
|
127
|
+
):
|
|
128
|
+
"""Export data with type validation"""
|
|
129
|
+
print(f"Exporting as {format.value}")
|
|
130
|
+
print(f"Date: {date}")
|
|
131
|
+
if tags:
|
|
132
|
+
print(f"Tags: {', '.join(tags)}")
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Environment & Config
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
@app.command()
|
|
139
|
+
@envvar("API_KEY", required=True)
|
|
140
|
+
@config_file("~/.config/myapp.yaml")
|
|
141
|
+
def api_call(api_key: str, config: dict):
|
|
142
|
+
"""Make API call using config"""
|
|
143
|
+
url = config.get("api_url")
|
|
144
|
+
print(f"Calling {url} with key {api_key[:4]}...")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Async Support
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
@app.command()
|
|
151
|
+
async def fetch_data():
|
|
152
|
+
"""Fetch data asynchronously"""
|
|
153
|
+
async with aiohttp.ClientSession() as session:
|
|
154
|
+
async with session.get("https://api.example.com") as resp:
|
|
155
|
+
data = await resp.json()
|
|
156
|
+
return data
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Plugin System
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
from webscout.swiftcli import Plugin
|
|
163
|
+
|
|
164
|
+
class MetricsPlugin(Plugin):
|
|
165
|
+
def __init__(self):
|
|
166
|
+
self.start_time = None
|
|
167
|
+
|
|
168
|
+
def before_command(self, command: str, args: list):
|
|
169
|
+
self.start_time = time.time()
|
|
170
|
+
|
|
171
|
+
def after_command(self, command: str, args: list, result: any):
|
|
172
|
+
duration = time.time() - self.start_time
|
|
173
|
+
print(f"Command {command} took {duration:.2f}s")
|
|
174
|
+
|
|
175
|
+
app.plugin_manager.register(MetricsPlugin())
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 🛠 Advanced Features
|
|
179
|
+
|
|
180
|
+
### Custom Output Formatting
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
from rich.console import Console
|
|
184
|
+
from rich.panel import Panel
|
|
185
|
+
from rich.table import Table
|
|
186
|
+
|
|
187
|
+
console = Console()
|
|
188
|
+
|
|
189
|
+
@app.command()
|
|
190
|
+
def status():
|
|
191
|
+
"""Show system status"""
|
|
192
|
+
table = Table(show_header=True)
|
|
193
|
+
table.add_column("Service")
|
|
194
|
+
table.add_column("Status")
|
|
195
|
+
table.add_column("Uptime")
|
|
196
|
+
|
|
197
|
+
table.add_row("API", "✅ Online", "24h")
|
|
198
|
+
table.add_row("DB", "✅ Online", "12h")
|
|
199
|
+
table.add_row("Cache", "⚠️ Degraded", "6h")
|
|
200
|
+
|
|
201
|
+
console.print(Panel(
|
|
202
|
+
table,
|
|
203
|
+
title="System Status",
|
|
204
|
+
border_style="green"
|
|
205
|
+
))
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Command Pipelines
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
@app.group(chain=True)
|
|
212
|
+
def process():
|
|
213
|
+
"""Data processing pipeline"""
|
|
214
|
+
pass
|
|
215
|
+
|
|
216
|
+
@process.command()
|
|
217
|
+
def extract():
|
|
218
|
+
"""Extract data"""
|
|
219
|
+
return {"data": [1, 2, 3]}
|
|
220
|
+
|
|
221
|
+
@process.command()
|
|
222
|
+
def transform(data: dict):
|
|
223
|
+
"""Transform data"""
|
|
224
|
+
return {"data": [x * 2 for x in data["data"]]}
|
|
225
|
+
|
|
226
|
+
@process.command()
|
|
227
|
+
def load(data: dict):
|
|
228
|
+
"""Load data"""
|
|
229
|
+
print(f"Loading: {data}")
|
|
230
|
+
|
|
231
|
+
# Usage: python app.py process extract transform load
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## 🔧 Configuration
|
|
235
|
+
|
|
236
|
+
### Application Config
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
app = CLI(
|
|
240
|
+
name="myapp",
|
|
241
|
+
version="1.0.0",
|
|
242
|
+
description="My awesome CLI app",
|
|
243
|
+
config_file="~/.config/myapp.yaml",
|
|
244
|
+
auto_envvar_prefix="MYAPP",
|
|
245
|
+
plugin_folder="~/.myapp/plugins"
|
|
246
|
+
)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Command Config
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
@app.command()
|
|
253
|
+
@option("--config", type=click.Path(exists=True))
|
|
254
|
+
@option("--verbose", "-v", count=True)
|
|
255
|
+
@option("--format", type=click.Choice(["json", "yaml"]))
|
|
256
|
+
def process(config: str, verbose: int, format: str):
|
|
257
|
+
"""Process with configuration"""
|
|
258
|
+
pass
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## 📋 Best Practices
|
|
262
|
+
|
|
263
|
+
1. **Use Type Hints**
|
|
264
|
+
```python
|
|
265
|
+
from typing import Optional, List, Dict
|
|
266
|
+
|
|
267
|
+
@app.command()
|
|
268
|
+
def search(
|
|
269
|
+
query: str,
|
|
270
|
+
limit: Optional[int] = 10,
|
|
271
|
+
tags: List[str] = None
|
|
272
|
+
) -> Dict[str, any]:
|
|
273
|
+
"""Search with proper type hints"""
|
|
274
|
+
pass
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
2. **Structured Error Handling**
|
|
278
|
+
```python
|
|
279
|
+
from webscout.swiftcli import CLIError
|
|
280
|
+
|
|
281
|
+
@app.command()
|
|
282
|
+
def risky():
|
|
283
|
+
try:
|
|
284
|
+
# Risky operation
|
|
285
|
+
pass
|
|
286
|
+
except FileNotFoundError as e:
|
|
287
|
+
raise CLIError("Config file not found") from e
|
|
288
|
+
except PermissionError as e:
|
|
289
|
+
raise CLIError("Permission denied") from e
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
3. **Command Organization**
|
|
293
|
+
```python
|
|
294
|
+
# commands/
|
|
295
|
+
# ├── __init__.py
|
|
296
|
+
# ├── db.py
|
|
297
|
+
# ├── auth.py
|
|
298
|
+
# └── utils.py
|
|
299
|
+
|
|
300
|
+
from .commands import db, auth, utils
|
|
301
|
+
|
|
302
|
+
app.add_command_group(db.commands)
|
|
303
|
+
app.add_command_group(auth.commands)
|
|
304
|
+
app.add_command_group(utils.commands)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## 🤝 Contributing
|
|
308
|
+
|
|
309
|
+
Contributions are welcome! Check out our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
310
|
+
|
|
311
|
+
## 📝 License
|
|
312
|
+
|
|
313
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
314
|
+
|
|
315
|
+
<div align="center">
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
Made with ❤️ by the [Webscout](https://github.com/OEvortex/Webscout) team
|
|
320
|
+
|
|
321
|
+
[](https://github.com/OEvortex/Webscout)
|
|
322
|
+
|
|
323
|
+
</div>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SwiftCLI - Build Beautiful Command-Line Applications at Light Speed
|
|
3
|
+
|
|
4
|
+
A modern, feature-rich CLI framework for building awesome command-line applications.
|
|
5
|
+
Built with love for the Python community!
|
|
6
|
+
|
|
7
|
+
Basic Usage:
|
|
8
|
+
>>> from swiftcli import CLI
|
|
9
|
+
>>> app = CLI(name="my-app", help="My awesome CLI app")
|
|
10
|
+
>>> @app.command()
|
|
11
|
+
... def hello(name: str):
|
|
12
|
+
... '''Say hello to someone'''
|
|
13
|
+
... print(f"Hello {name}!")
|
|
14
|
+
>>> app.run()
|
|
15
|
+
|
|
16
|
+
For more examples and documentation, visit:
|
|
17
|
+
https://github.com/OEvortex/Webscout/tree/main/webscout/swiftcli
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from .core.cli import CLI
|
|
21
|
+
from .core.group import Group
|
|
22
|
+
from .core.context import Context
|
|
23
|
+
from .plugins.base import Plugin
|
|
24
|
+
from .exceptions import (
|
|
25
|
+
SwiftCLIException,
|
|
26
|
+
UsageError,
|
|
27
|
+
BadParameter,
|
|
28
|
+
ConfigError,
|
|
29
|
+
PluginError
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Command decorators
|
|
33
|
+
from .decorators.command import (
|
|
34
|
+
command,
|
|
35
|
+
group,
|
|
36
|
+
argument,
|
|
37
|
+
flag,
|
|
38
|
+
pass_context
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Option decorators
|
|
42
|
+
from .decorators.options import (
|
|
43
|
+
option,
|
|
44
|
+
envvar,
|
|
45
|
+
config_file,
|
|
46
|
+
version_option,
|
|
47
|
+
help_option
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Output decorators
|
|
51
|
+
from .decorators.output import (
|
|
52
|
+
table_output,
|
|
53
|
+
progress,
|
|
54
|
+
panel_output,
|
|
55
|
+
format_output,
|
|
56
|
+
pager_output
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
__all__ = [
|
|
61
|
+
# Core classes
|
|
62
|
+
'CLI',
|
|
63
|
+
'Group',
|
|
64
|
+
'Context',
|
|
65
|
+
'Plugin',
|
|
66
|
+
|
|
67
|
+
# Exceptions
|
|
68
|
+
'SwiftCLIException',
|
|
69
|
+
'UsageError',
|
|
70
|
+
'BadParameter',
|
|
71
|
+
'ConfigError',
|
|
72
|
+
'PluginError',
|
|
73
|
+
|
|
74
|
+
# Command decorators
|
|
75
|
+
'command',
|
|
76
|
+
'group',
|
|
77
|
+
'argument',
|
|
78
|
+
'flag',
|
|
79
|
+
'pass_context',
|
|
80
|
+
|
|
81
|
+
# Option decorators
|
|
82
|
+
'option',
|
|
83
|
+
'envvar',
|
|
84
|
+
'config_file',
|
|
85
|
+
'version_option',
|
|
86
|
+
'help_option',
|
|
87
|
+
|
|
88
|
+
# Output decorators
|
|
89
|
+
'table_output',
|
|
90
|
+
'progress',
|
|
91
|
+
'panel_output',
|
|
92
|
+
'format_output',
|
|
93
|
+
'pager_output',
|
|
94
|
+
|
|
95
|
+
]
|