webscout 8.2.8__py3-none-any.whl → 8.3__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 (197) hide show
  1. webscout/AIauto.py +34 -16
  2. webscout/AIbase.py +96 -37
  3. webscout/AIutel.py +491 -87
  4. webscout/Bard.py +441 -323
  5. webscout/Extra/GitToolkit/__init__.py +10 -10
  6. webscout/Extra/YTToolkit/ytapi/video.py +232 -232
  7. webscout/Litlogger/README.md +10 -0
  8. webscout/Litlogger/__init__.py +7 -59
  9. webscout/Litlogger/formats.py +4 -0
  10. webscout/Litlogger/handlers.py +103 -0
  11. webscout/Litlogger/levels.py +13 -0
  12. webscout/Litlogger/logger.py +92 -0
  13. webscout/Provider/AISEARCH/Perplexity.py +332 -358
  14. webscout/Provider/AISEARCH/felo_search.py +9 -35
  15. webscout/Provider/AISEARCH/genspark_search.py +30 -56
  16. webscout/Provider/AISEARCH/hika_search.py +4 -16
  17. webscout/Provider/AISEARCH/iask_search.py +410 -436
  18. webscout/Provider/AISEARCH/monica_search.py +4 -30
  19. webscout/Provider/AISEARCH/scira_search.py +6 -32
  20. webscout/Provider/AISEARCH/webpilotai_search.py +38 -64
  21. webscout/Provider/Blackboxai.py +155 -35
  22. webscout/Provider/ChatSandbox.py +2 -1
  23. webscout/Provider/Deepinfra.py +339 -339
  24. webscout/Provider/ExaChat.py +358 -358
  25. webscout/Provider/Gemini.py +169 -169
  26. webscout/Provider/GithubChat.py +1 -2
  27. webscout/Provider/Glider.py +3 -3
  28. webscout/Provider/HeckAI.py +172 -82
  29. webscout/Provider/LambdaChat.py +1 -0
  30. webscout/Provider/MCPCore.py +7 -3
  31. webscout/Provider/OPENAI/BLACKBOXAI.py +421 -139
  32. webscout/Provider/OPENAI/Cloudflare.py +38 -21
  33. webscout/Provider/OPENAI/FalconH1.py +457 -0
  34. webscout/Provider/OPENAI/FreeGemini.py +35 -18
  35. webscout/Provider/OPENAI/NEMOTRON.py +34 -34
  36. webscout/Provider/OPENAI/PI.py +427 -0
  37. webscout/Provider/OPENAI/Qwen3.py +304 -0
  38. webscout/Provider/OPENAI/README.md +952 -1253
  39. webscout/Provider/OPENAI/TwoAI.py +374 -0
  40. webscout/Provider/OPENAI/__init__.py +7 -1
  41. webscout/Provider/OPENAI/ai4chat.py +73 -63
  42. webscout/Provider/OPENAI/api.py +869 -644
  43. webscout/Provider/OPENAI/base.py +2 -0
  44. webscout/Provider/OPENAI/c4ai.py +34 -13
  45. webscout/Provider/OPENAI/chatgpt.py +575 -556
  46. webscout/Provider/OPENAI/chatgptclone.py +512 -487
  47. webscout/Provider/OPENAI/chatsandbox.py +11 -6
  48. webscout/Provider/OPENAI/copilot.py +258 -0
  49. webscout/Provider/OPENAI/deepinfra.py +327 -318
  50. webscout/Provider/OPENAI/e2b.py +140 -104
  51. webscout/Provider/OPENAI/exaai.py +420 -411
  52. webscout/Provider/OPENAI/exachat.py +448 -443
  53. webscout/Provider/OPENAI/flowith.py +7 -3
  54. webscout/Provider/OPENAI/freeaichat.py +12 -8
  55. webscout/Provider/OPENAI/glider.py +15 -8
  56. webscout/Provider/OPENAI/groq.py +5 -2
  57. webscout/Provider/OPENAI/heckai.py +311 -307
  58. webscout/Provider/OPENAI/llmchatco.py +9 -7
  59. webscout/Provider/OPENAI/mcpcore.py +18 -9
  60. webscout/Provider/OPENAI/multichat.py +7 -5
  61. webscout/Provider/OPENAI/netwrck.py +16 -11
  62. webscout/Provider/OPENAI/oivscode.py +290 -0
  63. webscout/Provider/OPENAI/opkfc.py +507 -496
  64. webscout/Provider/OPENAI/pydantic_imports.py +172 -0
  65. webscout/Provider/OPENAI/scirachat.py +29 -17
  66. webscout/Provider/OPENAI/sonus.py +308 -303
  67. webscout/Provider/OPENAI/standardinput.py +442 -433
  68. webscout/Provider/OPENAI/textpollinations.py +18 -11
  69. webscout/Provider/OPENAI/toolbaz.py +419 -413
  70. webscout/Provider/OPENAI/typefully.py +17 -10
  71. webscout/Provider/OPENAI/typegpt.py +21 -11
  72. webscout/Provider/OPENAI/uncovrAI.py +477 -462
  73. webscout/Provider/OPENAI/utils.py +90 -79
  74. webscout/Provider/OPENAI/venice.py +435 -425
  75. webscout/Provider/OPENAI/wisecat.py +387 -381
  76. webscout/Provider/OPENAI/writecream.py +166 -163
  77. webscout/Provider/OPENAI/x0gpt.py +26 -37
  78. webscout/Provider/OPENAI/yep.py +384 -356
  79. webscout/Provider/PI.py +2 -1
  80. webscout/Provider/TTI/README.md +55 -101
  81. webscout/Provider/TTI/__init__.py +4 -9
  82. webscout/Provider/TTI/aiarta.py +365 -0
  83. webscout/Provider/TTI/artbit.py +0 -0
  84. webscout/Provider/TTI/base.py +64 -0
  85. webscout/Provider/TTI/fastflux.py +200 -0
  86. webscout/Provider/TTI/magicstudio.py +201 -0
  87. webscout/Provider/TTI/piclumen.py +203 -0
  88. webscout/Provider/TTI/pixelmuse.py +225 -0
  89. webscout/Provider/TTI/pollinations.py +221 -0
  90. webscout/Provider/TTI/utils.py +11 -0
  91. webscout/Provider/TTS/__init__.py +2 -1
  92. webscout/Provider/TTS/base.py +159 -159
  93. webscout/Provider/TTS/openai_fm.py +129 -0
  94. webscout/Provider/TextPollinationsAI.py +308 -308
  95. webscout/Provider/TwoAI.py +239 -44
  96. webscout/Provider/UNFINISHED/Youchat.py +330 -330
  97. webscout/Provider/UNFINISHED/puterjs.py +635 -0
  98. webscout/Provider/UNFINISHED/test_lmarena.py +119 -119
  99. webscout/Provider/Writecream.py +246 -246
  100. webscout/Provider/__init__.py +2 -2
  101. webscout/Provider/ai4chat.py +33 -8
  102. webscout/Provider/granite.py +41 -6
  103. webscout/Provider/koala.py +169 -169
  104. webscout/Provider/oivscode.py +309 -0
  105. webscout/Provider/samurai.py +3 -2
  106. webscout/Provider/scnet.py +1 -0
  107. webscout/Provider/typegpt.py +3 -3
  108. webscout/Provider/uncovr.py +368 -368
  109. webscout/client.py +70 -0
  110. webscout/litprinter/__init__.py +58 -58
  111. webscout/optimizers.py +419 -419
  112. webscout/scout/README.md +3 -1
  113. webscout/scout/core/crawler.py +134 -64
  114. webscout/scout/core/scout.py +148 -109
  115. webscout/scout/element.py +106 -88
  116. webscout/swiftcli/Readme.md +323 -323
  117. webscout/swiftcli/plugins/manager.py +9 -2
  118. webscout/version.py +1 -1
  119. webscout/zeroart/__init__.py +134 -134
  120. webscout/zeroart/effects.py +100 -100
  121. webscout/zeroart/fonts.py +1238 -1238
  122. {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/METADATA +160 -35
  123. webscout-8.3.dist-info/RECORD +290 -0
  124. {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/WHEEL +1 -1
  125. {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/entry_points.txt +1 -0
  126. webscout/Litlogger/Readme.md +0 -175
  127. webscout/Litlogger/core/__init__.py +0 -6
  128. webscout/Litlogger/core/level.py +0 -23
  129. webscout/Litlogger/core/logger.py +0 -165
  130. webscout/Litlogger/handlers/__init__.py +0 -12
  131. webscout/Litlogger/handlers/console.py +0 -33
  132. webscout/Litlogger/handlers/file.py +0 -143
  133. webscout/Litlogger/handlers/network.py +0 -173
  134. webscout/Litlogger/styles/__init__.py +0 -7
  135. webscout/Litlogger/styles/colors.py +0 -249
  136. webscout/Litlogger/styles/formats.py +0 -458
  137. webscout/Litlogger/styles/text.py +0 -87
  138. webscout/Litlogger/utils/__init__.py +0 -6
  139. webscout/Litlogger/utils/detectors.py +0 -153
  140. webscout/Litlogger/utils/formatters.py +0 -200
  141. webscout/Provider/ChatGPTGratis.py +0 -194
  142. webscout/Provider/TTI/AiForce/README.md +0 -159
  143. webscout/Provider/TTI/AiForce/__init__.py +0 -22
  144. webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
  145. webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
  146. webscout/Provider/TTI/FreeAIPlayground/README.md +0 -99
  147. webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
  148. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
  149. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
  150. webscout/Provider/TTI/ImgSys/README.md +0 -174
  151. webscout/Provider/TTI/ImgSys/__init__.py +0 -23
  152. webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
  153. webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
  154. webscout/Provider/TTI/MagicStudio/README.md +0 -101
  155. webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
  156. webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
  157. webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
  158. webscout/Provider/TTI/Nexra/README.md +0 -155
  159. webscout/Provider/TTI/Nexra/__init__.py +0 -22
  160. webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
  161. webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
  162. webscout/Provider/TTI/PollinationsAI/README.md +0 -146
  163. webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
  164. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
  165. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
  166. webscout/Provider/TTI/aiarta/README.md +0 -134
  167. webscout/Provider/TTI/aiarta/__init__.py +0 -2
  168. webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
  169. webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
  170. webscout/Provider/TTI/artbit/README.md +0 -100
  171. webscout/Provider/TTI/artbit/__init__.py +0 -22
  172. webscout/Provider/TTI/artbit/async_artbit.py +0 -155
  173. webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
  174. webscout/Provider/TTI/fastflux/README.md +0 -129
  175. webscout/Provider/TTI/fastflux/__init__.py +0 -22
  176. webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
  177. webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
  178. webscout/Provider/TTI/huggingface/README.md +0 -114
  179. webscout/Provider/TTI/huggingface/__init__.py +0 -22
  180. webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
  181. webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
  182. webscout/Provider/TTI/piclumen/README.md +0 -161
  183. webscout/Provider/TTI/piclumen/__init__.py +0 -23
  184. webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
  185. webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
  186. webscout/Provider/TTI/pixelmuse/README.md +0 -79
  187. webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
  188. webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
  189. webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
  190. webscout/Provider/TTI/talkai/README.md +0 -139
  191. webscout/Provider/TTI/talkai/__init__.py +0 -4
  192. webscout/Provider/TTI/talkai/async_talkai.py +0 -229
  193. webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
  194. webscout/Provider/UNFINISHED/oivscode.py +0 -351
  195. webscout-8.2.8.dist-info/RECORD +0 -334
  196. {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/licenses/LICENSE.md +0 -0
  197. {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/top_level.txt +0 -0
@@ -1,323 +1,323 @@
1
- <div align="center">
2
-
3
- # ⚡ SwiftCLI
4
-
5
- > Build Beautiful Command-Line Applications at Light Speed
6
-
7
- [![Python 3.8+](https://img.shields.io/badge/Python-3.8+-blue.svg?style=for-the-badge&logo=python&logoColor=white)](https://www.python.org)
8
- [![PyPI version](https://img.shields.io/badge/View_on-PyPI-orange.svg?style=for-the-badge&logo=pypi&logoColor=white)](https://pypi.org/project/webscout/)
9
- [![License](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](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
- [![GitHub stars](https://img.shields.io/github/stars/OEvortex/Webscout?style=social)](https://github.com/OEvortex/Webscout)
322
-
323
- </div>
1
+ <div align="center">
2
+
3
+ # ⚡ SwiftCLI
4
+
5
+ > Build Beautiful Command-Line Applications at Light Speed
6
+
7
+ [![Python 3.8+](https://img.shields.io/badge/Python-3.8+-blue.svg?style=for-the-badge&logo=python&logoColor=white)](https://www.python.org)
8
+ [![PyPI version](https://img.shields.io/badge/View_on-PyPI-orange.svg?style=for-the-badge&logo=pypi&logoColor=white)](https://pypi.org/project/webscout/)
9
+ [![License](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](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
+ [![GitHub stars](https://img.shields.io/github/stars/OEvortex/Webscout?style=social)](https://github.com/OEvortex/Webscout)
322
+
323
+ </div>
@@ -3,6 +3,7 @@
3
3
  import importlib
4
4
  import os
5
5
  import sys
6
+ import tempfile
6
7
  from pathlib import Path
7
8
  from typing import Any, Dict, List, Optional, Type
8
9
 
@@ -42,8 +43,14 @@ class PluginManager:
42
43
  plugin_dir: Optional custom plugin directory path
43
44
  """
44
45
  self.plugins: List[Plugin] = []
45
- self.plugin_dir = plugin_dir or os.path.expanduser("~/.swiftcli/plugins")
46
- os.makedirs(self.plugin_dir, exist_ok=True)
46
+ # Use temporary directory instead of ~/.swiftcli/plugins
47
+ if plugin_dir:
48
+ self.plugin_dir = plugin_dir
49
+ os.makedirs(self.plugin_dir, exist_ok=True)
50
+ else:
51
+ # Create a temporary directory that will be cleaned up when the process exits
52
+ self.temp_dir = tempfile.TemporaryDirectory(prefix="swiftcli_")
53
+ self.plugin_dir = self.temp_dir.name
47
54
 
48
55
  # Add plugin directory to Python path
49
56
  if self.plugin_dir not in sys.path:
webscout/version.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "8.2.8"
1
+ __version__ = "8.3"
2
2
  __prog__ = "webscout"