webscout 8.2.6__py3-none-any.whl → 8.2.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of webscout might be problematic. Click here for more details.

Files changed (292) hide show
  1. webscout/AIutel.py +97 -87
  2. webscout/version.py +1 -1
  3. {webscout-8.2.6.dist-info → webscout-8.2.7.dist-info}/METADATA +2 -15
  4. webscout-8.2.7.dist-info/RECORD +26 -0
  5. {webscout-8.2.6.dist-info → webscout-8.2.7.dist-info}/WHEEL +1 -1
  6. webscout-8.2.7.dist-info/entry_points.txt +3 -0
  7. webscout-8.2.7.dist-info/top_level.txt +1 -0
  8. webscout/Extra/GitToolkit/__init__.py +0 -10
  9. webscout/Extra/GitToolkit/gitapi/__init__.py +0 -12
  10. webscout/Extra/GitToolkit/gitapi/repository.py +0 -195
  11. webscout/Extra/GitToolkit/gitapi/user.py +0 -96
  12. webscout/Extra/GitToolkit/gitapi/utils.py +0 -62
  13. webscout/Extra/YTToolkit/YTdownloader.py +0 -957
  14. webscout/Extra/YTToolkit/__init__.py +0 -3
  15. webscout/Extra/YTToolkit/transcriber.py +0 -476
  16. webscout/Extra/YTToolkit/ytapi/__init__.py +0 -6
  17. webscout/Extra/YTToolkit/ytapi/channel.py +0 -307
  18. webscout/Extra/YTToolkit/ytapi/errors.py +0 -13
  19. webscout/Extra/YTToolkit/ytapi/extras.py +0 -45
  20. webscout/Extra/YTToolkit/ytapi/https.py +0 -88
  21. webscout/Extra/YTToolkit/ytapi/patterns.py +0 -61
  22. webscout/Extra/YTToolkit/ytapi/playlist.py +0 -59
  23. webscout/Extra/YTToolkit/ytapi/pool.py +0 -8
  24. webscout/Extra/YTToolkit/ytapi/query.py +0 -40
  25. webscout/Extra/YTToolkit/ytapi/stream.py +0 -63
  26. webscout/Extra/YTToolkit/ytapi/utils.py +0 -62
  27. webscout/Extra/YTToolkit/ytapi/video.py +0 -232
  28. webscout/Extra/__init__.py +0 -7
  29. webscout/Extra/autocoder/__init__.py +0 -9
  30. webscout/Extra/autocoder/autocoder.py +0 -910
  31. webscout/Extra/autocoder/autocoder_utiles.py +0 -332
  32. webscout/Extra/gguf.py +0 -684
  33. webscout/Extra/tempmail/__init__.py +0 -28
  34. webscout/Extra/tempmail/async_utils.py +0 -141
  35. webscout/Extra/tempmail/base.py +0 -161
  36. webscout/Extra/tempmail/cli.py +0 -187
  37. webscout/Extra/tempmail/emailnator.py +0 -84
  38. webscout/Extra/tempmail/mail_tm.py +0 -361
  39. webscout/Extra/tempmail/temp_mail_io.py +0 -292
  40. webscout/Extra/weather.py +0 -194
  41. webscout/Extra/weather_ascii.py +0 -76
  42. webscout/Litlogger/__init__.py +0 -67
  43. webscout/Litlogger/core/__init__.py +0 -6
  44. webscout/Litlogger/core/level.py +0 -23
  45. webscout/Litlogger/core/logger.py +0 -165
  46. webscout/Litlogger/handlers/__init__.py +0 -12
  47. webscout/Litlogger/handlers/console.py +0 -33
  48. webscout/Litlogger/handlers/file.py +0 -143
  49. webscout/Litlogger/handlers/network.py +0 -173
  50. webscout/Litlogger/styles/__init__.py +0 -7
  51. webscout/Litlogger/styles/colors.py +0 -249
  52. webscout/Litlogger/styles/formats.py +0 -458
  53. webscout/Litlogger/styles/text.py +0 -87
  54. webscout/Litlogger/utils/__init__.py +0 -6
  55. webscout/Litlogger/utils/detectors.py +0 -153
  56. webscout/Litlogger/utils/formatters.py +0 -200
  57. webscout/Provider/AI21.py +0 -177
  58. webscout/Provider/AISEARCH/DeepFind.py +0 -250
  59. webscout/Provider/AISEARCH/ISou.py +0 -256
  60. webscout/Provider/AISEARCH/Perplexity.py +0 -359
  61. webscout/Provider/AISEARCH/__init__.py +0 -10
  62. webscout/Provider/AISEARCH/felo_search.py +0 -228
  63. webscout/Provider/AISEARCH/genspark_search.py +0 -208
  64. webscout/Provider/AISEARCH/hika_search.py +0 -198
  65. webscout/Provider/AISEARCH/iask_search.py +0 -436
  66. webscout/Provider/AISEARCH/monica_search.py +0 -246
  67. webscout/Provider/AISEARCH/scira_search.py +0 -322
  68. webscout/Provider/AISEARCH/webpilotai_search.py +0 -281
  69. webscout/Provider/Aitopia.py +0 -316
  70. webscout/Provider/AllenAI.py +0 -447
  71. webscout/Provider/Andi.py +0 -228
  72. webscout/Provider/Blackboxai.py +0 -229
  73. webscout/Provider/ChatGPTClone.py +0 -237
  74. webscout/Provider/ChatGPTGratis.py +0 -194
  75. webscout/Provider/ChatSandbox.py +0 -342
  76. webscout/Provider/Cloudflare.py +0 -325
  77. webscout/Provider/Cohere.py +0 -208
  78. webscout/Provider/Deepinfra.py +0 -338
  79. webscout/Provider/ElectronHub.py +0 -773
  80. webscout/Provider/ExaAI.py +0 -261
  81. webscout/Provider/ExaChat.py +0 -358
  82. webscout/Provider/Free2GPT.py +0 -241
  83. webscout/Provider/GPTWeb.py +0 -249
  84. webscout/Provider/Gemini.py +0 -169
  85. webscout/Provider/GithubChat.py +0 -370
  86. webscout/Provider/GizAI.py +0 -285
  87. webscout/Provider/Glider.py +0 -222
  88. webscout/Provider/Groq.py +0 -801
  89. webscout/Provider/HF_space/__init__.py +0 -0
  90. webscout/Provider/HF_space/qwen_qwen2.py +0 -206
  91. webscout/Provider/HeckAI.py +0 -257
  92. webscout/Provider/HuggingFaceChat.py +0 -469
  93. webscout/Provider/Hunyuan.py +0 -283
  94. webscout/Provider/Jadve.py +0 -291
  95. webscout/Provider/Koboldai.py +0 -381
  96. webscout/Provider/LambdaChat.py +0 -411
  97. webscout/Provider/Llama3.py +0 -259
  98. webscout/Provider/MCPCore.py +0 -315
  99. webscout/Provider/Marcus.py +0 -206
  100. webscout/Provider/Nemotron.py +0 -218
  101. webscout/Provider/Netwrck.py +0 -270
  102. webscout/Provider/OLLAMA.py +0 -396
  103. webscout/Provider/OPENAI/__init__.py +0 -28
  104. webscout/Provider/OPENAI/ai4chat.py +0 -286
  105. webscout/Provider/OPENAI/base.py +0 -46
  106. webscout/Provider/OPENAI/c4ai.py +0 -367
  107. webscout/Provider/OPENAI/chatgpt.py +0 -549
  108. webscout/Provider/OPENAI/chatgptclone.py +0 -481
  109. webscout/Provider/OPENAI/deepinfra.py +0 -309
  110. webscout/Provider/OPENAI/e2b.py +0 -1350
  111. webscout/Provider/OPENAI/exaai.py +0 -404
  112. webscout/Provider/OPENAI/exachat.py +0 -437
  113. webscout/Provider/OPENAI/freeaichat.py +0 -352
  114. webscout/Provider/OPENAI/glider.py +0 -316
  115. webscout/Provider/OPENAI/groq.py +0 -354
  116. webscout/Provider/OPENAI/heckai.py +0 -341
  117. webscout/Provider/OPENAI/llmchatco.py +0 -327
  118. webscout/Provider/OPENAI/mcpcore.py +0 -376
  119. webscout/Provider/OPENAI/multichat.py +0 -368
  120. webscout/Provider/OPENAI/netwrck.py +0 -350
  121. webscout/Provider/OPENAI/opkfc.py +0 -488
  122. webscout/Provider/OPENAI/scirachat.py +0 -462
  123. webscout/Provider/OPENAI/sonus.py +0 -294
  124. webscout/Provider/OPENAI/standardinput.py +0 -425
  125. webscout/Provider/OPENAI/textpollinations.py +0 -329
  126. webscout/Provider/OPENAI/toolbaz.py +0 -406
  127. webscout/Provider/OPENAI/typegpt.py +0 -346
  128. webscout/Provider/OPENAI/uncovrAI.py +0 -455
  129. webscout/Provider/OPENAI/utils.py +0 -211
  130. webscout/Provider/OPENAI/venice.py +0 -413
  131. webscout/Provider/OPENAI/wisecat.py +0 -381
  132. webscout/Provider/OPENAI/writecream.py +0 -156
  133. webscout/Provider/OPENAI/x0gpt.py +0 -371
  134. webscout/Provider/OPENAI/yep.py +0 -327
  135. webscout/Provider/OpenGPT.py +0 -209
  136. webscout/Provider/Openai.py +0 -496
  137. webscout/Provider/PI.py +0 -429
  138. webscout/Provider/Perplexitylabs.py +0 -415
  139. webscout/Provider/QwenLM.py +0 -254
  140. webscout/Provider/Reka.py +0 -214
  141. webscout/Provider/StandardInput.py +0 -290
  142. webscout/Provider/TTI/AiForce/__init__.py +0 -22
  143. webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
  144. webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
  145. webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
  146. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
  147. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
  148. webscout/Provider/TTI/ImgSys/__init__.py +0 -23
  149. webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
  150. webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
  151. webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
  152. webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
  153. webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
  154. webscout/Provider/TTI/Nexra/__init__.py +0 -22
  155. webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
  156. webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
  157. webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
  158. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
  159. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
  160. webscout/Provider/TTI/__init__.py +0 -12
  161. webscout/Provider/TTI/aiarta/__init__.py +0 -2
  162. webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
  163. webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
  164. webscout/Provider/TTI/artbit/__init__.py +0 -22
  165. webscout/Provider/TTI/artbit/async_artbit.py +0 -155
  166. webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
  167. webscout/Provider/TTI/fastflux/__init__.py +0 -22
  168. webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
  169. webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
  170. webscout/Provider/TTI/huggingface/__init__.py +0 -22
  171. webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
  172. webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
  173. webscout/Provider/TTI/piclumen/__init__.py +0 -23
  174. webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
  175. webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
  176. webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
  177. webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
  178. webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
  179. webscout/Provider/TTI/talkai/__init__.py +0 -4
  180. webscout/Provider/TTI/talkai/async_talkai.py +0 -229
  181. webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
  182. webscout/Provider/TTS/__init__.py +0 -8
  183. webscout/Provider/TTS/base.py +0 -159
  184. webscout/Provider/TTS/deepgram.py +0 -156
  185. webscout/Provider/TTS/elevenlabs.py +0 -111
  186. webscout/Provider/TTS/gesserit.py +0 -128
  187. webscout/Provider/TTS/murfai.py +0 -113
  188. webscout/Provider/TTS/parler.py +0 -111
  189. webscout/Provider/TTS/speechma.py +0 -180
  190. webscout/Provider/TTS/streamElements.py +0 -333
  191. webscout/Provider/TTS/utils.py +0 -280
  192. webscout/Provider/TeachAnything.py +0 -233
  193. webscout/Provider/TextPollinationsAI.py +0 -306
  194. webscout/Provider/TwoAI.py +0 -280
  195. webscout/Provider/TypliAI.py +0 -305
  196. webscout/Provider/Venice.py +0 -258
  197. webscout/Provider/VercelAI.py +0 -253
  198. webscout/Provider/WiseCat.py +0 -233
  199. webscout/Provider/WrDoChat.py +0 -370
  200. webscout/Provider/Writecream.py +0 -237
  201. webscout/Provider/WritingMate.py +0 -269
  202. webscout/Provider/Youchat.py +0 -330
  203. webscout/Provider/__init__.py +0 -178
  204. webscout/Provider/ai4chat.py +0 -203
  205. webscout/Provider/aimathgpt.py +0 -189
  206. webscout/Provider/akashgpt.py +0 -335
  207. webscout/Provider/asksteve.py +0 -212
  208. webscout/Provider/bagoodex.py +0 -145
  209. webscout/Provider/cerebras.py +0 -288
  210. webscout/Provider/chatglm.py +0 -215
  211. webscout/Provider/cleeai.py +0 -213
  212. webscout/Provider/copilot.py +0 -425
  213. webscout/Provider/elmo.py +0 -283
  214. webscout/Provider/freeaichat.py +0 -285
  215. webscout/Provider/geminiapi.py +0 -208
  216. webscout/Provider/geminiprorealtime.py +0 -160
  217. webscout/Provider/granite.py +0 -235
  218. webscout/Provider/hermes.py +0 -266
  219. webscout/Provider/julius.py +0 -223
  220. webscout/Provider/koala.py +0 -268
  221. webscout/Provider/learnfastai.py +0 -325
  222. webscout/Provider/llama3mitril.py +0 -215
  223. webscout/Provider/llmchat.py +0 -255
  224. webscout/Provider/llmchatco.py +0 -306
  225. webscout/Provider/meta.py +0 -798
  226. webscout/Provider/multichat.py +0 -364
  227. webscout/Provider/scira_chat.py +0 -297
  228. webscout/Provider/scnet.py +0 -243
  229. webscout/Provider/searchchat.py +0 -292
  230. webscout/Provider/sonus.py +0 -258
  231. webscout/Provider/talkai.py +0 -194
  232. webscout/Provider/toolbaz.py +0 -353
  233. webscout/Provider/turboseek.py +0 -266
  234. webscout/Provider/typefully.py +0 -330
  235. webscout/Provider/typegpt.py +0 -289
  236. webscout/Provider/uncovr.py +0 -368
  237. webscout/Provider/x0gpt.py +0 -299
  238. webscout/Provider/yep.py +0 -389
  239. webscout/litagent/__init__.py +0 -29
  240. webscout/litagent/agent.py +0 -455
  241. webscout/litagent/constants.py +0 -60
  242. webscout/litprinter/__init__.py +0 -59
  243. webscout/scout/__init__.py +0 -8
  244. webscout/scout/core/__init__.py +0 -7
  245. webscout/scout/core/crawler.py +0 -140
  246. webscout/scout/core/scout.py +0 -568
  247. webscout/scout/core/search_result.py +0 -96
  248. webscout/scout/core/text_analyzer.py +0 -63
  249. webscout/scout/core/text_utils.py +0 -277
  250. webscout/scout/core/web_analyzer.py +0 -52
  251. webscout/scout/core.py +0 -881
  252. webscout/scout/element.py +0 -460
  253. webscout/scout/parsers/__init__.py +0 -69
  254. webscout/scout/parsers/html5lib_parser.py +0 -172
  255. webscout/scout/parsers/html_parser.py +0 -236
  256. webscout/scout/parsers/lxml_parser.py +0 -178
  257. webscout/scout/utils.py +0 -37
  258. webscout/swiftcli/__init__.py +0 -95
  259. webscout/swiftcli/core/__init__.py +0 -7
  260. webscout/swiftcli/core/cli.py +0 -297
  261. webscout/swiftcli/core/context.py +0 -104
  262. webscout/swiftcli/core/group.py +0 -241
  263. webscout/swiftcli/decorators/__init__.py +0 -28
  264. webscout/swiftcli/decorators/command.py +0 -221
  265. webscout/swiftcli/decorators/options.py +0 -220
  266. webscout/swiftcli/decorators/output.py +0 -252
  267. webscout/swiftcli/exceptions.py +0 -21
  268. webscout/swiftcli/plugins/__init__.py +0 -9
  269. webscout/swiftcli/plugins/base.py +0 -135
  270. webscout/swiftcli/plugins/manager.py +0 -262
  271. webscout/swiftcli/utils/__init__.py +0 -59
  272. webscout/swiftcli/utils/formatting.py +0 -252
  273. webscout/swiftcli/utils/parsing.py +0 -267
  274. webscout/zeroart/__init__.py +0 -55
  275. webscout/zeroart/base.py +0 -60
  276. webscout/zeroart/effects.py +0 -99
  277. webscout/zeroart/fonts.py +0 -816
  278. webscout-8.2.6.dist-info/RECORD +0 -307
  279. webscout-8.2.6.dist-info/entry_points.txt +0 -3
  280. webscout-8.2.6.dist-info/top_level.txt +0 -2
  281. webstoken/__init__.py +0 -30
  282. webstoken/classifier.py +0 -189
  283. webstoken/keywords.py +0 -216
  284. webstoken/language.py +0 -128
  285. webstoken/ner.py +0 -164
  286. webstoken/normalizer.py +0 -35
  287. webstoken/processor.py +0 -77
  288. webstoken/sentiment.py +0 -206
  289. webstoken/stemmer.py +0 -73
  290. webstoken/tagger.py +0 -60
  291. webstoken/tokenizer.py +0 -158
  292. {webscout-8.2.6.dist-info → webscout-8.2.7.dist-info}/licenses/LICENSE.md +0 -0
@@ -1,297 +0,0 @@
1
- """Main CLI application class."""
2
-
3
- import sys
4
- from typing import Any, Dict, List, Optional, Union
5
-
6
- from rich.console import Console
7
-
8
- from ..exceptions import UsageError
9
- from ..plugins.manager import PluginManager
10
- from ..utils.formatting import format_error, format_success
11
- from .context import Context
12
-
13
- console = Console()
14
-
15
- class CLI:
16
- """
17
- Main CLI application class.
18
-
19
- The CLI class is the core of SwiftCLI. It handles command registration,
20
- argument parsing, and command execution. It also manages plugins and
21
- provides the main entry point for CLI applications.
22
-
23
- Attributes:
24
- name: Application name
25
- help: Application description
26
- version: Application version
27
- debug: Debug mode flag
28
- commands: Registered commands
29
- groups: Command groups
30
- plugin_manager: Plugin manager instance
31
-
32
- Example:
33
- >>> app = CLI(name="myapp", version="1.0.0")
34
- >>> @app.command()
35
- ... def greet(name: str):
36
- ... '''Greet someone'''
37
- ... print(f"Hello {name}!")
38
- >>> app.run()
39
- """
40
-
41
- def __init__(
42
- self,
43
- name: str,
44
- help: Optional[str] = None,
45
- version: Optional[str] = None,
46
- debug: bool = False
47
- ):
48
- """
49
- Initialize CLI application.
50
-
51
- Args:
52
- name: Application name
53
- help: Application description
54
- version: Application version
55
- debug: Enable debug mode
56
- """
57
- self.name = name
58
- self.help = help
59
- self.version = version
60
- self.debug = debug
61
-
62
- self.commands: Dict[str, Dict[str, Any]] = {}
63
- self.groups: Dict[str, 'Group'] = {} # type: ignore
64
- self.plugin_manager = PluginManager()
65
-
66
- # Initialize plugin manager with this CLI instance
67
- self.plugin_manager.init_plugins(self)
68
-
69
- def command(
70
- self,
71
- name: Optional[str] = None,
72
- help: Optional[str] = None,
73
- aliases: Optional[List[str]] = None,
74
- hidden: bool = False
75
- ):
76
- """
77
- Decorator to register a command.
78
-
79
- Args:
80
- name: Command name (defaults to function name)
81
- help: Command help text
82
- aliases: Alternative command names
83
- hidden: Hide from help output
84
-
85
- Example:
86
- @app.command()
87
- def hello(name: str):
88
- '''Say hello'''
89
- print(f"Hello {name}!")
90
- """
91
- def decorator(f):
92
- cmd_name = name or f.__name__
93
- self.commands[cmd_name] = {
94
- 'func': f,
95
- 'help': help or f.__doc__,
96
- 'aliases': aliases or [],
97
- 'hidden': hidden
98
- }
99
-
100
- # Register aliases
101
- for alias in (aliases or []):
102
- self.commands[alias] = self.commands[cmd_name]
103
-
104
- return f
105
- return decorator
106
-
107
- def group(
108
- self,
109
- name: Optional[str] = None,
110
- help: Optional[str] = None,
111
- **kwargs
112
- ):
113
- """
114
- Create a command group.
115
-
116
- Args:
117
- name: Group name
118
- help: Group help text
119
- **kwargs: Additional group options
120
-
121
- Example:
122
- @app.group()
123
- def db():
124
- '''Database commands'''
125
- pass
126
-
127
- @db.command()
128
- def migrate():
129
- '''Run migrations'''
130
- pass
131
- """
132
- from .group import Group # Import here to avoid circular dependency
133
-
134
- def decorator(f):
135
- group_name = name or f.__name__
136
- group = Group(
137
- name=group_name,
138
- help=help or f.__doc__,
139
- parent=self,
140
- **kwargs
141
- )
142
- self.groups[group_name] = group
143
- return group
144
- return decorator
145
-
146
- def run(self, args: Optional[List[str]] = None) -> int:
147
- """
148
- Run the CLI application.
149
-
150
- Args:
151
- args: Command line arguments (defaults to sys.argv[1:])
152
-
153
- Returns:
154
- Exit code (0 for success, non-zero for error)
155
- """
156
- try:
157
- args = args or sys.argv[1:]
158
-
159
- # Show help if no arguments
160
- if not args or args[0] in ['-h', '--help']:
161
- self._print_help()
162
- return 0
163
-
164
- # Show version if requested
165
- if args[0] in ['-v', '--version'] and self.version:
166
- console.print(self.version)
167
- return 0
168
-
169
- command_name = args[0]
170
- command_args = args[1:]
171
-
172
- # Check if it's a group command
173
- if command_name in self.groups:
174
- return self.groups[command_name].run(command_args)
175
-
176
- # Check if it's a regular command
177
- if command_name not in self.commands:
178
- format_error(f"Unknown command: {command_name}")
179
- self._print_help()
180
- return 1
181
-
182
- # Create command context
183
- ctx = Context(self, command=command_name, debug=self.debug)
184
-
185
- # Run command through plugin system
186
- if not self.plugin_manager.before_command(command_name, command_args):
187
- return 1
188
-
189
- try:
190
- command = self.commands[command_name]
191
- result = command['func'](**self._parse_args(command, command_args))
192
- self.plugin_manager.after_command(command_name, command_args, result)
193
- return 0
194
- except Exception as e:
195
- self.plugin_manager.on_error(command_name, e)
196
- if self.debug:
197
- raise
198
- format_error(str(e))
199
- return 1
200
-
201
- except KeyboardInterrupt:
202
- console.print("\nOperation cancelled by user")
203
- return 130
204
- except Exception as e:
205
- if self.debug:
206
- raise
207
- format_error(str(e))
208
- return 1
209
-
210
- def _parse_args(self, command: Dict[str, Any], args: List[str]) -> Dict[str, Any]:
211
- """Parse command arguments."""
212
- from ..utils.parsing import (
213
- parse_args, validate_required, convert_type,
214
- validate_choice, get_env_var
215
- )
216
-
217
- params = {}
218
- func = command['func']
219
-
220
- # Parse command-line arguments
221
- parsed_args = parse_args(args)
222
-
223
- # Handle options
224
- if hasattr(func, '_options'):
225
- for opt in func._options:
226
- name = opt['param_decls'][0].lstrip('-').replace('-', '_')
227
- if name in parsed_args:
228
- value = parsed_args[name]
229
- if 'type' in opt:
230
- value = convert_type(value, opt['type'], name)
231
- if 'choices' in opt and opt['choices']:
232
- validate_choice(
233
- value,
234
- opt['choices'],
235
- name,
236
- opt.get('case_sensitive', True)
237
- )
238
- params[name] = value
239
- elif opt.get('required', False):
240
- raise UsageError(f"Missing required option: {name}")
241
- elif 'default' in opt:
242
- params[name] = opt['default']
243
-
244
- # Handle arguments
245
- if hasattr(func, '_arguments'):
246
- for i, arg in enumerate(func._arguments):
247
- name = arg['name']
248
- if f'arg{i}' in parsed_args:
249
- value = parsed_args[f'arg{i}']
250
- if 'type' in arg:
251
- value = convert_type(value, arg['type'], name)
252
- params[name] = value
253
- elif arg.get('required', True):
254
- raise UsageError(f"Missing required argument: {name}")
255
- elif 'default' in arg:
256
- params[name] = arg['default']
257
-
258
- # Handle environment variables
259
- if hasattr(func, '_envvars'):
260
- for env in func._envvars:
261
- name = env['name'].lower()
262
- value = get_env_var(
263
- env['name'],
264
- env.get('type', str),
265
- env.get('required', False),
266
- env.get('default')
267
- )
268
- if value is not None:
269
- params[name] = value
270
-
271
- return params
272
-
273
- def _print_help(self) -> None:
274
- """Print application help message."""
275
- console.print(f"\n[bold]{self.name}[/]")
276
- if self.help:
277
- console.print(f"\n{self.help}")
278
-
279
- # Show commands
280
- console.print("\n[bold]Commands:[/]")
281
- for name, cmd in self.commands.items():
282
- if not cmd.get('hidden', False):
283
- console.print(f" {name:20} {cmd['help'] or ''}")
284
-
285
- # Show command groups
286
- for name, group in self.groups.items():
287
- console.print(f"\n[bold]{name} commands:[/]")
288
- for cmd_name, cmd in group.commands.items():
289
- if not cmd.get('hidden', False):
290
- console.print(f" {cmd_name:20} {cmd['help'] or ''}")
291
-
292
- console.print("\nUse -h or --help with any command for more info")
293
- if self.version:
294
- console.print("Use -v or --version to show version")
295
-
296
- def __repr__(self) -> str:
297
- return f"<CLI name={self.name}>"
@@ -1,104 +0,0 @@
1
- """Context handling for SwiftCLI."""
2
-
3
- from typing import Any, Dict, Optional
4
-
5
- class Context:
6
- """
7
- Context object that holds state for the CLI app.
8
-
9
- The Context class provides access to the CLI application instance and maintains
10
- state throughout command execution. It can be used to pass data between
11
- commands and access global configuration.
12
-
13
- Attributes:
14
- cli: The CLI application instance.
15
- parent: The parent context if this is a subcommand.
16
- command: The current command name.
17
- obj: An object that can be used to store arbitrary data.
18
- params: Dictionary of current command parameters.
19
- debug: Debug mode flag.
20
-
21
- Example:
22
- @app.command()
23
- @pass_context
24
- def status(ctx):
25
- '''Show application status'''
26
- print(f"App: {ctx.cli.name}")
27
- print(f"Debug: {ctx.debug}")
28
- """
29
-
30
- def __init__(
31
- self,
32
- cli: 'CLI', # type: ignore
33
- parent: Optional['Context'] = None,
34
- command: Optional[str] = None,
35
- obj: Any = None,
36
- debug: bool = False
37
- ):
38
- self.cli = cli
39
- self.parent = parent
40
- self.command = command
41
- self.obj = obj
42
- self.params: Dict[str, Any] = {}
43
- self.debug = debug
44
-
45
- def get_parameter(self, name: str, default: Any = None) -> Any:
46
- """
47
- Get a parameter value from the context.
48
-
49
- Args:
50
- name: Parameter name
51
- default: Default value if parameter not found
52
-
53
- Returns:
54
- Parameter value or default
55
- """
56
- return self.params.get(name, default)
57
-
58
- def set_parameter(self, name: str, value: Any) -> None:
59
- """
60
- Set a parameter value in the context.
61
-
62
- Args:
63
- name: Parameter name
64
- value: Parameter value
65
- """
66
- self.params[name] = value
67
-
68
- def get_parent_context(self) -> Optional['Context']:
69
- """Get the parent context if it exists."""
70
- return self.parent
71
-
72
- def create_child_context(
73
- self,
74
- command: Optional[str] = None,
75
- obj: Any = None
76
- ) -> 'Context':
77
- """
78
- Create a new child context.
79
-
80
- Args:
81
- command: Command name for the child context
82
- obj: Object to store in child context
83
-
84
- Returns:
85
- New child context
86
- """
87
- return Context(
88
- cli=self.cli,
89
- parent=self,
90
- command=command,
91
- obj=obj,
92
- debug=self.debug
93
- )
94
-
95
- @property
96
- def root_context(self) -> 'Context':
97
- """Get the root context by traversing up the parent chain."""
98
- ctx = self
99
- while ctx.parent is not None:
100
- ctx = ctx.parent
101
- return ctx
102
-
103
- def __repr__(self) -> str:
104
- return f"<Context command={self.command}>"
@@ -1,241 +0,0 @@
1
- """Command group handling for SwiftCLI."""
2
-
3
- from typing import Any, Dict, List, Optional, TYPE_CHECKING
4
-
5
- from rich.console import Console
6
-
7
- from ..exceptions import UsageError
8
- from ..utils.formatting import format_error
9
- from .context import Context
10
-
11
- if TYPE_CHECKING:
12
- from .cli import CLI
13
-
14
- console = Console()
15
-
16
- class Group:
17
- """
18
- Command group that can contain subcommands.
19
-
20
- Groups allow organizing related commands together and support command
21
- chaining for building command pipelines.
22
-
23
- Attributes:
24
- name: Group name
25
- help: Group description
26
- commands: Registered commands
27
- parent: Parent CLI instance
28
- chain: Enable command chaining
29
- invoke_without_command: Allow invoking group without subcommand
30
-
31
- Example:
32
- @app.group()
33
- def db():
34
- '''Database commands'''
35
- pass
36
-
37
- @db.command()
38
- def migrate():
39
- '''Run database migrations'''
40
- print("Running migrations...")
41
- """
42
-
43
- def __init__(
44
- self,
45
- name: str,
46
- help: Optional[str] = None,
47
- parent: Optional['CLI'] = None,
48
- chain: bool = False,
49
- invoke_without_command: bool = False
50
- ):
51
- """
52
- Initialize command group.
53
-
54
- Args:
55
- name: Group name
56
- help: Group description
57
- parent: Parent CLI instance
58
- chain: Enable command chaining
59
- invoke_without_command: Allow invoking group without subcommand
60
- """
61
- self.name = name
62
- self.help = help
63
- self.parent = parent
64
- self.chain = chain
65
- self.invoke_without_command = invoke_without_command
66
- self.commands: Dict[str, Dict[str, Any]] = {}
67
-
68
- def command(
69
- self,
70
- name: Optional[str] = None,
71
- help: Optional[str] = None,
72
- aliases: Optional[List[str]] = None,
73
- hidden: bool = False
74
- ):
75
- """
76
- Decorator to register a command in this group.
77
-
78
- Args:
79
- name: Command name (defaults to function name)
80
- help: Command help text
81
- aliases: Alternative command names
82
- hidden: Hide from help output
83
-
84
- Example:
85
- @group.command()
86
- def status():
87
- '''Show status'''
88
- print("Status: OK")
89
- """
90
- def decorator(f):
91
- cmd_name = name or f.__name__
92
- self.commands[cmd_name] = {
93
- 'func': f,
94
- 'help': help or f.__doc__,
95
- 'aliases': aliases or [],
96
- 'hidden': hidden
97
- }
98
-
99
- # Register aliases
100
- for alias in (aliases or []):
101
- self.commands[alias] = self.commands[cmd_name]
102
-
103
- return f
104
- return decorator
105
-
106
- def group(
107
- self,
108
- name: Optional[str] = None,
109
- help: Optional[str] = None,
110
- **kwargs
111
- ):
112
- """
113
- Create a subgroup within this group.
114
-
115
- Args:
116
- name: Subgroup name
117
- help: Subgroup help text
118
- **kwargs: Additional group options
119
-
120
- Example:
121
- @group.group()
122
- def config():
123
- '''Configuration commands'''
124
- pass
125
- """
126
- def decorator(f):
127
- subgroup = Group(
128
- name=name or f.__name__,
129
- help=help or f.__doc__,
130
- parent=self.parent,
131
- **kwargs
132
- )
133
- self.commands[subgroup.name] = subgroup
134
- return subgroup
135
- return decorator
136
-
137
- def run(self, args: List[str]) -> int:
138
- """
139
- Run a command in this group.
140
-
141
- Args:
142
- args: Command arguments
143
-
144
- Returns:
145
- Exit code (0 for success, non-zero for error)
146
- """
147
- try:
148
- # Show help if no arguments or help requested
149
- if not args or args[0] in ['-h', '--help']:
150
- self._print_help()
151
- return 0
152
-
153
- command_name = args[0]
154
- command_args = args[1:]
155
-
156
- # Check if command exists
157
- if command_name not in self.commands:
158
- format_error(f"Unknown command: {self.name} {command_name}")
159
- self._print_help()
160
- return 1
161
-
162
- command = self.commands[command_name]
163
-
164
- # Handle nested groups
165
- if isinstance(command, Group):
166
- return command.run(command_args)
167
-
168
- # Create command context
169
- ctx = Context(
170
- self.parent,
171
- command=f"{self.name} {command_name}",
172
- debug=getattr(self.parent, 'debug', False)
173
- )
174
-
175
- # Run command through plugin system
176
- if self.parent and not self.parent.plugin_manager.before_command(
177
- f"{self.name} {command_name}",
178
- command_args
179
- ):
180
- return 1
181
-
182
- try:
183
- result = command['func'](**self._parse_args(command, command_args))
184
-
185
- if self.parent:
186
- self.parent.plugin_manager.after_command(
187
- f"{self.name} {command_name}",
188
- command_args,
189
- result
190
- )
191
-
192
- # Handle command chaining
193
- if self.chain and result is not None:
194
- return result
195
-
196
- return 0
197
-
198
- except Exception as e:
199
- if self.parent:
200
- self.parent.plugin_manager.on_error(
201
- f"{self.name} {command_name}",
202
- e
203
- )
204
- if getattr(self.parent, 'debug', False):
205
- raise
206
- format_error(str(e))
207
- return 1
208
-
209
- except Exception as e:
210
- if getattr(self.parent, 'debug', False):
211
- raise
212
- format_error(str(e))
213
- return 1
214
-
215
- def _parse_args(self, command: Dict[str, Any], args: List[str]) -> Dict[str, Any]:
216
- """Parse command arguments."""
217
- # Use parent CLI's argument parser if available
218
- if self.parent:
219
- return self.parent._parse_args(command, args)
220
-
221
- # Fallback to basic argument parsing
222
- from ..utils.parsing import parse_args
223
- return parse_args(args)
224
-
225
- def _print_help(self) -> None:
226
- """Print group help message."""
227
- console.print(f"\n[bold]{self.name}[/] - {self.help or ''}")
228
-
229
- console.print("\n[bold]Commands:[/]")
230
- for name, cmd in self.commands.items():
231
- if isinstance(cmd, Group):
232
- console.print(f" {name} [group]")
233
- if cmd.help:
234
- console.print(f" {cmd.help}")
235
- elif not cmd.get('hidden', False):
236
- console.print(f" {name:20} {cmd['help'] or ''}")
237
-
238
- console.print("\nUse -h or --help with any command for more info")
239
-
240
- def __repr__(self) -> str:
241
- return f"<Group name={self.name}>"
@@ -1,28 +0,0 @@
1
- """Decorators for SwiftCLI."""
2
-
3
- from .command import command, group, argument, flag, pass_context
4
- from .options import option, envvar, config_file, version_option, help_option
5
- from .output import table_output, progress, panel_output, format_output, pager_output
6
-
7
- __all__ = [
8
- # Command decorators
9
- 'command',
10
- 'group',
11
- 'argument',
12
- 'flag',
13
- 'pass_context',
14
-
15
- # Option decorators
16
- 'option',
17
- 'envvar',
18
- 'config_file',
19
- 'version_option',
20
- 'help_option',
21
-
22
- # Output decorators
23
- 'table_output',
24
- 'progress',
25
- 'panel_output',
26
- 'format_output',
27
- 'pager_output'
28
- ]