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.

Files changed (323) hide show
  1. webscout/AIauto.py +1 -1
  2. webscout/AIutel.py +298 -249
  3. webscout/Extra/Act.md +309 -0
  4. webscout/Extra/GitToolkit/__init__.py +10 -0
  5. webscout/Extra/GitToolkit/gitapi/README.md +110 -0
  6. webscout/Extra/GitToolkit/gitapi/__init__.py +12 -0
  7. webscout/Extra/GitToolkit/gitapi/repository.py +195 -0
  8. webscout/Extra/GitToolkit/gitapi/user.py +96 -0
  9. webscout/Extra/GitToolkit/gitapi/utils.py +62 -0
  10. webscout/Extra/YTToolkit/README.md +375 -0
  11. webscout/Extra/YTToolkit/YTdownloader.py +957 -0
  12. webscout/Extra/YTToolkit/__init__.py +3 -0
  13. webscout/Extra/YTToolkit/transcriber.py +476 -0
  14. webscout/Extra/YTToolkit/ytapi/README.md +44 -0
  15. webscout/Extra/YTToolkit/ytapi/__init__.py +6 -0
  16. webscout/Extra/YTToolkit/ytapi/channel.py +307 -0
  17. webscout/Extra/YTToolkit/ytapi/errors.py +13 -0
  18. webscout/Extra/YTToolkit/ytapi/extras.py +118 -0
  19. webscout/Extra/YTToolkit/ytapi/https.py +88 -0
  20. webscout/Extra/YTToolkit/ytapi/patterns.py +61 -0
  21. webscout/Extra/YTToolkit/ytapi/playlist.py +59 -0
  22. webscout/Extra/YTToolkit/ytapi/pool.py +8 -0
  23. webscout/Extra/YTToolkit/ytapi/query.py +40 -0
  24. webscout/Extra/YTToolkit/ytapi/stream.py +63 -0
  25. webscout/Extra/YTToolkit/ytapi/utils.py +62 -0
  26. webscout/Extra/YTToolkit/ytapi/video.py +232 -0
  27. webscout/Extra/__init__.py +7 -0
  28. webscout/Extra/autocoder/__init__.py +9 -0
  29. webscout/Extra/autocoder/autocoder.py +1105 -0
  30. webscout/Extra/autocoder/autocoder_utiles.py +332 -0
  31. webscout/Extra/gguf.md +430 -0
  32. webscout/Extra/gguf.py +684 -0
  33. webscout/Extra/tempmail/README.md +488 -0
  34. webscout/Extra/tempmail/__init__.py +28 -0
  35. webscout/Extra/tempmail/async_utils.py +141 -0
  36. webscout/Extra/tempmail/base.py +161 -0
  37. webscout/Extra/tempmail/cli.py +187 -0
  38. webscout/Extra/tempmail/emailnator.py +84 -0
  39. webscout/Extra/tempmail/mail_tm.py +361 -0
  40. webscout/Extra/tempmail/temp_mail_io.py +292 -0
  41. webscout/Extra/weather.md +281 -0
  42. webscout/Extra/weather.py +194 -0
  43. webscout/Extra/weather_ascii.py +76 -0
  44. webscout/Litlogger/Readme.md +175 -0
  45. webscout/Litlogger/__init__.py +67 -0
  46. webscout/Litlogger/core/__init__.py +6 -0
  47. webscout/Litlogger/core/level.py +23 -0
  48. webscout/Litlogger/core/logger.py +165 -0
  49. webscout/Litlogger/handlers/__init__.py +12 -0
  50. webscout/Litlogger/handlers/console.py +33 -0
  51. webscout/Litlogger/handlers/file.py +143 -0
  52. webscout/Litlogger/handlers/network.py +173 -0
  53. webscout/Litlogger/styles/__init__.py +7 -0
  54. webscout/Litlogger/styles/colors.py +249 -0
  55. webscout/Litlogger/styles/formats.py +458 -0
  56. webscout/Litlogger/styles/text.py +87 -0
  57. webscout/Litlogger/utils/__init__.py +6 -0
  58. webscout/Litlogger/utils/detectors.py +153 -0
  59. webscout/Litlogger/utils/formatters.py +200 -0
  60. webscout/Provider/AI21.py +177 -0
  61. webscout/Provider/AISEARCH/DeepFind.py +254 -0
  62. webscout/Provider/AISEARCH/Perplexity.py +359 -0
  63. webscout/Provider/AISEARCH/README.md +279 -0
  64. webscout/Provider/AISEARCH/__init__.py +9 -0
  65. webscout/Provider/AISEARCH/felo_search.py +228 -0
  66. webscout/Provider/AISEARCH/genspark_search.py +350 -0
  67. webscout/Provider/AISEARCH/hika_search.py +198 -0
  68. webscout/Provider/AISEARCH/iask_search.py +436 -0
  69. webscout/Provider/AISEARCH/monica_search.py +246 -0
  70. webscout/Provider/AISEARCH/scira_search.py +324 -0
  71. webscout/Provider/AISEARCH/webpilotai_search.py +281 -0
  72. webscout/Provider/Aitopia.py +316 -0
  73. webscout/Provider/AllenAI.py +440 -0
  74. webscout/Provider/Andi.py +228 -0
  75. webscout/Provider/Blackboxai.py +673 -0
  76. webscout/Provider/ChatGPTClone.py +237 -0
  77. webscout/Provider/ChatGPTGratis.py +194 -0
  78. webscout/Provider/ChatSandbox.py +342 -0
  79. webscout/Provider/Cloudflare.py +324 -0
  80. webscout/Provider/Cohere.py +208 -0
  81. webscout/Provider/Deepinfra.py +340 -0
  82. webscout/Provider/ExaAI.py +261 -0
  83. webscout/Provider/ExaChat.py +358 -0
  84. webscout/Provider/Flowith.py +217 -0
  85. webscout/Provider/FreeGemini.py +250 -0
  86. webscout/Provider/Gemini.py +169 -0
  87. webscout/Provider/GithubChat.py +370 -0
  88. webscout/Provider/GizAI.py +295 -0
  89. webscout/Provider/Glider.py +225 -0
  90. webscout/Provider/Groq.py +801 -0
  91. webscout/Provider/HF_space/__init__.py +0 -0
  92. webscout/Provider/HF_space/qwen_qwen2.py +206 -0
  93. webscout/Provider/HeckAI.py +285 -0
  94. webscout/Provider/HuggingFaceChat.py +469 -0
  95. webscout/Provider/Hunyuan.py +283 -0
  96. webscout/Provider/Jadve.py +291 -0
  97. webscout/Provider/Koboldai.py +384 -0
  98. webscout/Provider/LambdaChat.py +411 -0
  99. webscout/Provider/Llama3.py +259 -0
  100. webscout/Provider/MCPCore.py +315 -0
  101. webscout/Provider/Marcus.py +198 -0
  102. webscout/Provider/Nemotron.py +218 -0
  103. webscout/Provider/Netwrck.py +270 -0
  104. webscout/Provider/OLLAMA.py +396 -0
  105. webscout/Provider/OPENAI/BLACKBOXAI.py +735 -0
  106. webscout/Provider/OPENAI/Cloudflare.py +378 -0
  107. webscout/Provider/OPENAI/FreeGemini.py +282 -0
  108. webscout/Provider/OPENAI/NEMOTRON.py +244 -0
  109. webscout/Provider/OPENAI/README.md +1253 -0
  110. webscout/Provider/OPENAI/__init__.py +36 -0
  111. webscout/Provider/OPENAI/ai4chat.py +293 -0
  112. webscout/Provider/OPENAI/api.py +810 -0
  113. webscout/Provider/OPENAI/base.py +249 -0
  114. webscout/Provider/OPENAI/c4ai.py +373 -0
  115. webscout/Provider/OPENAI/chatgpt.py +556 -0
  116. webscout/Provider/OPENAI/chatgptclone.py +488 -0
  117. webscout/Provider/OPENAI/chatsandbox.py +172 -0
  118. webscout/Provider/OPENAI/deepinfra.py +319 -0
  119. webscout/Provider/OPENAI/e2b.py +1356 -0
  120. webscout/Provider/OPENAI/exaai.py +411 -0
  121. webscout/Provider/OPENAI/exachat.py +443 -0
  122. webscout/Provider/OPENAI/flowith.py +162 -0
  123. webscout/Provider/OPENAI/freeaichat.py +359 -0
  124. webscout/Provider/OPENAI/glider.py +323 -0
  125. webscout/Provider/OPENAI/groq.py +361 -0
  126. webscout/Provider/OPENAI/heckai.py +307 -0
  127. webscout/Provider/OPENAI/llmchatco.py +335 -0
  128. webscout/Provider/OPENAI/mcpcore.py +383 -0
  129. webscout/Provider/OPENAI/multichat.py +376 -0
  130. webscout/Provider/OPENAI/netwrck.py +356 -0
  131. webscout/Provider/OPENAI/opkfc.py +496 -0
  132. webscout/Provider/OPENAI/scirachat.py +471 -0
  133. webscout/Provider/OPENAI/sonus.py +303 -0
  134. webscout/Provider/OPENAI/standardinput.py +433 -0
  135. webscout/Provider/OPENAI/textpollinations.py +339 -0
  136. webscout/Provider/OPENAI/toolbaz.py +413 -0
  137. webscout/Provider/OPENAI/typefully.py +355 -0
  138. webscout/Provider/OPENAI/typegpt.py +358 -0
  139. webscout/Provider/OPENAI/uncovrAI.py +462 -0
  140. webscout/Provider/OPENAI/utils.py +307 -0
  141. webscout/Provider/OPENAI/venice.py +425 -0
  142. webscout/Provider/OPENAI/wisecat.py +381 -0
  143. webscout/Provider/OPENAI/writecream.py +163 -0
  144. webscout/Provider/OPENAI/x0gpt.py +378 -0
  145. webscout/Provider/OPENAI/yep.py +356 -0
  146. webscout/Provider/OpenGPT.py +209 -0
  147. webscout/Provider/Openai.py +496 -0
  148. webscout/Provider/PI.py +429 -0
  149. webscout/Provider/Perplexitylabs.py +415 -0
  150. webscout/Provider/QwenLM.py +254 -0
  151. webscout/Provider/Reka.py +214 -0
  152. webscout/Provider/StandardInput.py +290 -0
  153. webscout/Provider/TTI/AiForce/README.md +159 -0
  154. webscout/Provider/TTI/AiForce/__init__.py +22 -0
  155. webscout/Provider/TTI/AiForce/async_aiforce.py +224 -0
  156. webscout/Provider/TTI/AiForce/sync_aiforce.py +245 -0
  157. webscout/Provider/TTI/FreeAIPlayground/README.md +99 -0
  158. webscout/Provider/TTI/FreeAIPlayground/__init__.py +9 -0
  159. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +181 -0
  160. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +180 -0
  161. webscout/Provider/TTI/ImgSys/README.md +174 -0
  162. webscout/Provider/TTI/ImgSys/__init__.py +23 -0
  163. webscout/Provider/TTI/ImgSys/async_imgsys.py +202 -0
  164. webscout/Provider/TTI/ImgSys/sync_imgsys.py +195 -0
  165. webscout/Provider/TTI/MagicStudio/README.md +101 -0
  166. webscout/Provider/TTI/MagicStudio/__init__.py +2 -0
  167. webscout/Provider/TTI/MagicStudio/async_magicstudio.py +111 -0
  168. webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +109 -0
  169. webscout/Provider/TTI/Nexra/README.md +155 -0
  170. webscout/Provider/TTI/Nexra/__init__.py +22 -0
  171. webscout/Provider/TTI/Nexra/async_nexra.py +286 -0
  172. webscout/Provider/TTI/Nexra/sync_nexra.py +258 -0
  173. webscout/Provider/TTI/PollinationsAI/README.md +146 -0
  174. webscout/Provider/TTI/PollinationsAI/__init__.py +23 -0
  175. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +311 -0
  176. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +265 -0
  177. webscout/Provider/TTI/README.md +128 -0
  178. webscout/Provider/TTI/__init__.py +12 -0
  179. webscout/Provider/TTI/aiarta/README.md +134 -0
  180. webscout/Provider/TTI/aiarta/__init__.py +2 -0
  181. webscout/Provider/TTI/aiarta/async_aiarta.py +482 -0
  182. webscout/Provider/TTI/aiarta/sync_aiarta.py +440 -0
  183. webscout/Provider/TTI/artbit/README.md +100 -0
  184. webscout/Provider/TTI/artbit/__init__.py +22 -0
  185. webscout/Provider/TTI/artbit/async_artbit.py +155 -0
  186. webscout/Provider/TTI/artbit/sync_artbit.py +148 -0
  187. webscout/Provider/TTI/fastflux/README.md +129 -0
  188. webscout/Provider/TTI/fastflux/__init__.py +22 -0
  189. webscout/Provider/TTI/fastflux/async_fastflux.py +261 -0
  190. webscout/Provider/TTI/fastflux/sync_fastflux.py +252 -0
  191. webscout/Provider/TTI/huggingface/README.md +114 -0
  192. webscout/Provider/TTI/huggingface/__init__.py +22 -0
  193. webscout/Provider/TTI/huggingface/async_huggingface.py +199 -0
  194. webscout/Provider/TTI/huggingface/sync_huggingface.py +195 -0
  195. webscout/Provider/TTI/piclumen/README.md +161 -0
  196. webscout/Provider/TTI/piclumen/__init__.py +23 -0
  197. webscout/Provider/TTI/piclumen/async_piclumen.py +268 -0
  198. webscout/Provider/TTI/piclumen/sync_piclumen.py +233 -0
  199. webscout/Provider/TTI/pixelmuse/README.md +79 -0
  200. webscout/Provider/TTI/pixelmuse/__init__.py +4 -0
  201. webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +249 -0
  202. webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +182 -0
  203. webscout/Provider/TTI/talkai/README.md +139 -0
  204. webscout/Provider/TTI/talkai/__init__.py +4 -0
  205. webscout/Provider/TTI/talkai/async_talkai.py +229 -0
  206. webscout/Provider/TTI/talkai/sync_talkai.py +207 -0
  207. webscout/Provider/TTS/README.md +192 -0
  208. webscout/Provider/TTS/__init__.py +9 -0
  209. webscout/Provider/TTS/base.py +159 -0
  210. webscout/Provider/TTS/deepgram.py +156 -0
  211. webscout/Provider/TTS/elevenlabs.py +111 -0
  212. webscout/Provider/TTS/gesserit.py +128 -0
  213. webscout/Provider/TTS/murfai.py +113 -0
  214. webscout/Provider/TTS/parler.py +111 -0
  215. webscout/Provider/TTS/speechma.py +580 -0
  216. webscout/Provider/TTS/sthir.py +94 -0
  217. webscout/Provider/TTS/streamElements.py +333 -0
  218. webscout/Provider/TTS/utils.py +280 -0
  219. webscout/Provider/TeachAnything.py +229 -0
  220. webscout/Provider/TextPollinationsAI.py +308 -0
  221. webscout/Provider/TwoAI.py +280 -0
  222. webscout/Provider/TypliAI.py +305 -0
  223. webscout/Provider/UNFINISHED/ChatHub.py +209 -0
  224. webscout/Provider/UNFINISHED/Youchat.py +330 -0
  225. webscout/Provider/UNFINISHED/liner_api_request.py +263 -0
  226. webscout/Provider/UNFINISHED/oivscode.py +351 -0
  227. webscout/Provider/UNFINISHED/test_lmarena.py +119 -0
  228. webscout/Provider/Venice.py +258 -0
  229. webscout/Provider/VercelAI.py +253 -0
  230. webscout/Provider/WiseCat.py +233 -0
  231. webscout/Provider/WrDoChat.py +370 -0
  232. webscout/Provider/Writecream.py +246 -0
  233. webscout/Provider/WritingMate.py +269 -0
  234. webscout/Provider/__init__.py +172 -0
  235. webscout/Provider/ai4chat.py +149 -0
  236. webscout/Provider/akashgpt.py +335 -0
  237. webscout/Provider/asksteve.py +220 -0
  238. webscout/Provider/cerebras.py +290 -0
  239. webscout/Provider/chatglm.py +215 -0
  240. webscout/Provider/cleeai.py +213 -0
  241. webscout/Provider/copilot.py +425 -0
  242. webscout/Provider/elmo.py +283 -0
  243. webscout/Provider/freeaichat.py +285 -0
  244. webscout/Provider/geminiapi.py +208 -0
  245. webscout/Provider/granite.py +235 -0
  246. webscout/Provider/hermes.py +266 -0
  247. webscout/Provider/julius.py +223 -0
  248. webscout/Provider/koala.py +170 -0
  249. webscout/Provider/learnfastai.py +325 -0
  250. webscout/Provider/llama3mitril.py +215 -0
  251. webscout/Provider/llmchat.py +258 -0
  252. webscout/Provider/llmchatco.py +306 -0
  253. webscout/Provider/lmarena.py +198 -0
  254. webscout/Provider/meta.py +801 -0
  255. webscout/Provider/multichat.py +364 -0
  256. webscout/Provider/samurai.py +223 -0
  257. webscout/Provider/scira_chat.py +299 -0
  258. webscout/Provider/scnet.py +243 -0
  259. webscout/Provider/searchchat.py +292 -0
  260. webscout/Provider/sonus.py +258 -0
  261. webscout/Provider/talkai.py +194 -0
  262. webscout/Provider/toolbaz.py +353 -0
  263. webscout/Provider/turboseek.py +266 -0
  264. webscout/Provider/typefully.py +202 -0
  265. webscout/Provider/typegpt.py +289 -0
  266. webscout/Provider/uncovr.py +368 -0
  267. webscout/Provider/x0gpt.py +299 -0
  268. webscout/Provider/yep.py +389 -0
  269. webscout/__init__.py +4 -2
  270. webscout/cli.py +3 -28
  271. webscout/conversation.py +35 -35
  272. webscout/litagent/Readme.md +276 -0
  273. webscout/litagent/__init__.py +29 -0
  274. webscout/litagent/agent.py +455 -0
  275. webscout/litagent/constants.py +60 -0
  276. webscout/litprinter/__init__.py +59 -0
  277. webscout/scout/README.md +402 -0
  278. webscout/scout/__init__.py +8 -0
  279. webscout/scout/core/__init__.py +7 -0
  280. webscout/scout/core/crawler.py +140 -0
  281. webscout/scout/core/scout.py +568 -0
  282. webscout/scout/core/search_result.py +96 -0
  283. webscout/scout/core/text_analyzer.py +63 -0
  284. webscout/scout/core/text_utils.py +277 -0
  285. webscout/scout/core/web_analyzer.py +52 -0
  286. webscout/scout/element.py +460 -0
  287. webscout/scout/parsers/__init__.py +69 -0
  288. webscout/scout/parsers/html5lib_parser.py +172 -0
  289. webscout/scout/parsers/html_parser.py +236 -0
  290. webscout/scout/parsers/lxml_parser.py +178 -0
  291. webscout/scout/utils.py +37 -0
  292. webscout/swiftcli/Readme.md +323 -0
  293. webscout/swiftcli/__init__.py +95 -0
  294. webscout/swiftcli/core/__init__.py +7 -0
  295. webscout/swiftcli/core/cli.py +297 -0
  296. webscout/swiftcli/core/context.py +104 -0
  297. webscout/swiftcli/core/group.py +241 -0
  298. webscout/swiftcli/decorators/__init__.py +28 -0
  299. webscout/swiftcli/decorators/command.py +221 -0
  300. webscout/swiftcli/decorators/options.py +220 -0
  301. webscout/swiftcli/decorators/output.py +252 -0
  302. webscout/swiftcli/exceptions.py +21 -0
  303. webscout/swiftcli/plugins/__init__.py +9 -0
  304. webscout/swiftcli/plugins/base.py +135 -0
  305. webscout/swiftcli/plugins/manager.py +262 -0
  306. webscout/swiftcli/utils/__init__.py +59 -0
  307. webscout/swiftcli/utils/formatting.py +252 -0
  308. webscout/swiftcli/utils/parsing.py +267 -0
  309. webscout/version.py +1 -1
  310. webscout/webscout_search.py +2 -182
  311. webscout/webscout_search_async.py +1 -179
  312. webscout/zeroart/README.md +89 -0
  313. webscout/zeroart/__init__.py +135 -0
  314. webscout/zeroart/base.py +66 -0
  315. webscout/zeroart/effects.py +101 -0
  316. webscout/zeroart/fonts.py +1239 -0
  317. {webscout-8.2.7.dist-info → webscout-8.2.8.dist-info}/METADATA +115 -60
  318. webscout-8.2.8.dist-info/RECORD +334 -0
  319. {webscout-8.2.7.dist-info → webscout-8.2.8.dist-info}/WHEEL +1 -1
  320. webscout-8.2.7.dist-info/RECORD +0 -26
  321. {webscout-8.2.7.dist-info → webscout-8.2.8.dist-info}/entry_points.txt +0 -0
  322. {webscout-8.2.7.dist-info → webscout-8.2.8.dist-info}/licenses/LICENSE.md +0 -0
  323. {webscout-8.2.7.dist-info → webscout-8.2.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,281 @@
1
+ <div align="center">
2
+ <h1>☀️ Webscout Weather Toolkit</h1>
3
+ <p><strong>Comprehensive weather data retrieval and visualization tools</strong></p>
4
+
5
+ <!-- Badges -->
6
+ <p>
7
+ <a href="#-installation"><img src="https://img.shields.io/badge/Easy-Installation-success?style=flat-square" alt="Easy Installation"></a>
8
+ <a href="#-current-weather-data"><img src="https://img.shields.io/badge/Real--time-Data-blue?style=flat-square" alt="Real-time Data"></a>
9
+ <a href="#-ascii-art-weather"><img src="https://img.shields.io/badge/ASCII-Visualization-orange?style=flat-square" alt="ASCII Visualization"></a>
10
+ </p>
11
+ </div>
12
+
13
+ > [!NOTE]
14
+ > Webscout's Weather Toolkit provides powerful tools to retrieve and display weather information in various formats, including structured data and ASCII art visualization.
15
+
16
+ ## 📋 Table of Contents
17
+
18
+ - [🚀 Installation](#-installation)
19
+ - [🌡️ Current Weather Data](#-current-weather-data)
20
+ - [🔮 Weather Forecast](#-weather-forecast)
21
+ - [🎨 ASCII Art Weather](#-ascii-art-weather)
22
+ - [📊 Data Structure](#-data-structure)
23
+ - [⚙️ Advanced Usage](#-advanced-usage)
24
+
25
+ ## 🚀 Installation
26
+
27
+ The Weather Toolkit is included in the Webscout package. Install or update Webscout to get access:
28
+
29
+ ```bash
30
+ pip install -U webscout
31
+ ```
32
+
33
+ ## 🌡️ Current Weather Data
34
+
35
+ Retrieve structured current weather information for any location worldwide.
36
+
37
+ ```python
38
+ from webscout.Extra import weather
39
+
40
+ # Get weather for a specific location
41
+ forecast = weather.get("London")
42
+
43
+ # Access current conditions
44
+ print(f"Current weather: {forecast.summary}")
45
+
46
+ # Access temperature details
47
+ if forecast.current_condition:
48
+ print(f"Temperature: {forecast.current_condition.temp_c}°C / {forecast.current_condition.temp_f}°F")
49
+ print(f"Feels like: {forecast.current_condition.feels_like_c}°C")
50
+ print(f"Conditions: {forecast.current_condition.weather_desc}")
51
+ print(f"Wind: {forecast.current_condition.wind_speed_kmph} km/h from {forecast.current_condition.wind_direction}")
52
+ print(f"Humidity: {forecast.current_condition.humidity}%")
53
+ print(f"Visibility: {forecast.current_condition.visibility} km")
54
+ print(f"Pressure: {forecast.current_condition.pressure} mb")
55
+ ```
56
+
57
+ ## 🔮 Weather Forecast
58
+
59
+ Access detailed forecast information for today and upcoming days.
60
+
61
+ ```python
62
+ from webscout.Extra import weather
63
+
64
+ forecast = weather.get("Tokyo")
65
+
66
+ # Today's forecast
67
+ if forecast.today:
68
+ print(f"Today ({forecast.today.date_formatted}):")
69
+ print(f" Temperature range: {forecast.today.min_temp_c}°C - {forecast.today.max_temp_c}°C")
70
+ print(f" Sunrise: {forecast.today.sunrise}, Sunset: {forecast.today.sunset}")
71
+
72
+ # Access hourly forecasts
73
+ if forecast.today.hourly and len(forecast.today.hourly) > 4:
74
+ noon = forecast.today.hourly[4] # Noon (12:00) is usually index 4
75
+ print(f" Noon conditions: {noon.weather_desc}")
76
+ print(f" Chance of rain: {noon.chance_of_rain}%")
77
+ print(f" Humidity: {noon.humidity}%")
78
+ print(f" UV Index: {noon.uv_index}")
79
+
80
+ # Tomorrow's forecast
81
+ if forecast.tomorrow:
82
+ print(f"\nTomorrow ({forecast.tomorrow.date_formatted}):")
83
+ print(f" Temperature range: {forecast.tomorrow.min_temp_c}°C - {forecast.tomorrow.max_temp_c}°C")
84
+ print(f" Weather: {forecast.tomorrow.weather_desc}")
85
+ print(f" Sunrise: {forecast.tomorrow.sunrise}, Sunset: {forecast.tomorrow.sunset}")
86
+
87
+ # Extended forecast (next 3 days)
88
+ if forecast.days and len(forecast.days) > 2:
89
+ print("\nExtended Forecast:")
90
+ for day in forecast.days[2:5]: # Days 3-5
91
+ print(f" {day.date_formatted}: {day.min_temp_c}°C - {day.max_temp_c}°C, {day.weather_desc}")
92
+ ```
93
+
94
+ ## 🎨 ASCII Art Weather
95
+
96
+ Retrieve weather information as visually appealing ASCII art.
97
+
98
+ ```python
99
+ from webscout.Extra import weather_ascii
100
+
101
+ # Get ASCII art weather
102
+ result = weather_ascii.get("Paris")
103
+
104
+ # Display the ASCII art weather
105
+ print(result.content)
106
+
107
+ # Get ASCII art with temperature in Fahrenheit
108
+ result_f = weather_ascii.get("New York", units="imperial")
109
+ print(result_f.content)
110
+
111
+ # Get ASCII art with a specific number of forecast days
112
+ result_days = weather_ascii.get("Berlin", days=3)
113
+ print(result_days.content)
114
+ ```
115
+
116
+ Example output:
117
+ ```
118
+ Weather for Paris, France
119
+
120
+ \ / Clear
121
+ .-. +20°C
122
+ ― ( ) ― ↗ 11 km/h
123
+ `-' 10 km
124
+ / \ 0.0 mm
125
+ ┌─────────────┐
126
+ ┌───────────────────────┤ Wed 14 Apr ├───────────────────────┐
127
+ │ Morning └──────┬──────┘ Evening Night │
128
+ ├──────────────────────────────┼──────────────────────────────┤
129
+ │ Cloudy │ Clear │
130
+ │ .--. +20..+22 °C │ \ / +15 °C │
131
+ │ .-( ). ↗ 11-13 km/h │ .-. ↗ 7-9 km/h │
132
+ │ (___.__)__) 10 km │ ― ( ) ― 10 km │
133
+ │ 0.0 mm | 0% │ `-' 0.0 mm | 0% │
134
+ └──────────────────────────────┴──────────────────────────────┘
135
+ ```
136
+
137
+ ## 📊 Data Structure
138
+
139
+ The Weather Toolkit returns structured data objects with the following key components:
140
+
141
+ <details>
142
+ <summary><strong>Forecast Object Structure</strong></summary>
143
+
144
+ ```python
145
+ forecast = weather.get("London")
146
+
147
+ # Main forecast object attributes
148
+ forecast.location # Location information (city, country, etc.)
149
+ forecast.summary # Brief summary of current weather
150
+ forecast.current_condition # Current weather conditions
151
+ forecast.today # Today's forecast
152
+ forecast.tomorrow # Tomorrow's forecast
153
+ forecast.days # List of daily forecasts (including today and tomorrow)
154
+
155
+ # Current condition attributes
156
+ current = forecast.current_condition
157
+ current.temp_c # Temperature in Celsius
158
+ current.temp_f # Temperature in Fahrenheit
159
+ current.feels_like_c # "Feels like" temperature in Celsius
160
+ current.feels_like_f # "Feels like" temperature in Fahrenheit
161
+ current.wind_speed_kmph # Wind speed in km/h
162
+ current.wind_speed_mph # Wind speed in mph
163
+ current.wind_direction # Wind direction (e.g., "NW")
164
+ current.humidity # Humidity percentage
165
+ current.pressure # Atmospheric pressure in millibars
166
+ current.visibility # Visibility in kilometers
167
+ current.weather_desc # Weather description (e.g., "Partly cloudy")
168
+ current.weather_code # Weather code for icon mapping
169
+
170
+ # Daily forecast attributes
171
+ day = forecast.today # or any day from forecast.days
172
+ day.date # Date (YYYY-MM-DD)
173
+ day.date_formatted # Formatted date (e.g., "Wed 14 Apr")
174
+ day.max_temp_c # Maximum temperature in Celsius
175
+ day.min_temp_c # Minimum temperature in Celsius
176
+ day.max_temp_f # Maximum temperature in Fahrenheit
177
+ day.min_temp_f # Minimum temperature in Fahrenheit
178
+ day.sunrise # Sunrise time
179
+ day.sunset # Sunset time
180
+ day.weather_desc # Weather description
181
+ day.weather_code # Weather code
182
+ day.hourly # List of hourly forecasts for this day
183
+ ```
184
+ </details>
185
+
186
+ <details>
187
+ <summary><strong>ASCII Weather Object Structure</strong></summary>
188
+
189
+ ```python
190
+ result = weather_ascii.get("Paris")
191
+
192
+ # ASCII result attributes
193
+ result.content # The full ASCII art weather display
194
+ result.location # Location information
195
+ result.temperature # Current temperature
196
+ result.conditions # Current weather conditions
197
+ result.forecast_days # Number of forecast days included
198
+ ```
199
+ </details>
200
+
201
+ ## ⚙️ Advanced Usage
202
+
203
+ <details>
204
+ <summary><strong>Custom Location Formats</strong></summary>
205
+
206
+ The Weather Toolkit supports various location formats:
207
+
208
+ ```python
209
+ # City name
210
+ weather.get("London")
211
+
212
+ # City and country
213
+ weather.get("Paris, France")
214
+
215
+ # ZIP/Postal code (US)
216
+ weather.get("10001") # New York, NY
217
+
218
+ # Latitude and Longitude
219
+ weather.get("40.7128,-74.0060") # New York coordinates
220
+ ```
221
+ </details>
222
+
223
+ <details>
224
+ <summary><strong>Temperature Units</strong></summary>
225
+
226
+ Control temperature units in ASCII weather display:
227
+
228
+ ```python
229
+ # Default (metric - Celsius)
230
+ weather_ascii.get("Tokyo")
231
+
232
+ # Imperial (Fahrenheit)
233
+ weather_ascii.get("New York", units="imperial")
234
+
235
+ # Metric (Celsius)
236
+ weather_ascii.get("Berlin", units="metric")
237
+ ```
238
+ </details>
239
+
240
+ <details>
241
+ <summary><strong>Forecast Days</strong></summary>
242
+
243
+ Control the number of forecast days in ASCII weather display:
244
+
245
+ ```python
246
+ # Default (1 day)
247
+ weather_ascii.get("Sydney")
248
+
249
+ # 3-day forecast
250
+ weather_ascii.get("Rio de Janeiro", days=3)
251
+
252
+ # 5-day forecast (maximum)
253
+ weather_ascii.get("Moscow", days=5)
254
+ ```
255
+ </details>
256
+
257
+ <details>
258
+ <summary><strong>Error Handling</strong></summary>
259
+
260
+ Implement proper error handling for robust applications:
261
+
262
+ ```python
263
+ from webscout.Extra import weather
264
+ from webscout.exceptions import APIError
265
+
266
+ try:
267
+ forecast = weather.get("London")
268
+ print(f"Current temperature: {forecast.current_condition.temp_c}°C")
269
+ except APIError as e:
270
+ print(f"API Error: {e}")
271
+ except Exception as e:
272
+ print(f"An error occurred: {e}")
273
+ ```
274
+ </details>
275
+
276
+ <div align="center">
277
+ <p>
278
+ <a href="https://github.com/OEvortex/Webscout"><img alt="GitHub Repository" src="https://img.shields.io/badge/GitHub-Repository-181717?style=for-the-badge&logo=github&logoColor=white"></a>
279
+ <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>
280
+ </p>
281
+ </div>
@@ -0,0 +1,194 @@
1
+ """
2
+ Weather information module with a clean, strongly-typed API structure.
3
+
4
+ This module provides a simple client for fetching weather data
5
+ from the wttr.in service with proper typing and a consistent interface.
6
+ """
7
+
8
+ import requests
9
+ from datetime import datetime
10
+ from typing import List, Dict, Any, Optional
11
+
12
+
13
+ class CurrentCondition:
14
+ """Current weather conditions with strongly typed properties."""
15
+
16
+ def __init__(self, data: Dict[str, Any]) -> None:
17
+ """Initialize with current condition data.
18
+
19
+ Args:
20
+ data: Current condition data dictionary from wttr.in
21
+ """
22
+ self.temp_c: Optional[str] = data.get('temp_C')
23
+ self.temp_f: Optional[str] = data.get('temp_F')
24
+ self.feels_like_c: Optional[str] = data.get('FeelsLikeC')
25
+ self.feels_like_f: Optional[str] = data.get('FeelsLikeF')
26
+ self.weather_desc: str = data.get('weatherDesc', [{}])[0].get('value', '')
27
+ self.weather_code: Optional[str] = data.get('weatherCode')
28
+ self.humidity: Optional[str] = data.get('humidity')
29
+ self.visibility: Optional[str] = data.get('visibility')
30
+ self.pressure: Optional[str] = data.get('pressure')
31
+ self.wind_speed_kmph: Optional[str] = data.get('windspeedKmph')
32
+ self.wind_direction: Optional[str] = data.get('winddir16Point')
33
+ self.wind_degree: Optional[str] = data.get('winddirDegree')
34
+
35
+
36
+ class Location:
37
+ """Location information with strongly typed properties."""
38
+
39
+ def __init__(self, data: Dict[str, Any]) -> None:
40
+ """Initialize with location data.
41
+
42
+ Args:
43
+ data: Location data dictionary from wttr.in
44
+ """
45
+ self.name: str = data.get('areaName', [{}])[0].get('value', '')
46
+ self.country: str = data.get('country', [{}])[0].get('value', '')
47
+ self.region: str = data.get('region', [{}])[0].get('value', '')
48
+ self.latitude: Optional[str] = data.get('latitude')
49
+ self.longitude: Optional[str] = data.get('longitude')
50
+
51
+
52
+ class HourlyForecast:
53
+ """Hourly forecast information with strongly typed properties."""
54
+
55
+ def __init__(self, data: Dict[str, Any]) -> None:
56
+ """Initialize with hourly forecast data.
57
+
58
+ Args:
59
+ data: Hourly forecast data dictionary from wttr.in
60
+ """
61
+ self.time: Optional[str] = data.get('time')
62
+ self.temp_c: Optional[str] = data.get('tempC')
63
+ self.temp_f: Optional[str] = data.get('tempF')
64
+ self.weather_desc: str = data.get('weatherDesc', [{}])[0].get('value', '')
65
+ self.weather_code: Optional[str] = data.get('weatherCode')
66
+ self.wind_speed_kmph: Optional[str] = data.get('windspeedKmph')
67
+ self.wind_direction: Optional[str] = data.get('winddir16Point')
68
+ self.feels_like_c: Optional[str] = data.get('FeelsLikeC')
69
+ self.feels_like_f: Optional[str] = data.get('FeelsLikeF')
70
+ self.chance_of_rain: Optional[str] = data.get('chanceofrain')
71
+ self.chance_of_snow: Optional[str] = data.get('chanceofsnow')
72
+
73
+
74
+ class DayForecast:
75
+ """Daily forecast information with strongly typed properties."""
76
+
77
+ def __init__(self, data: Dict[str, Any]) -> None:
78
+ """Initialize with daily forecast data.
79
+
80
+ Args:
81
+ data: Daily forecast data dictionary from wttr.in
82
+ """
83
+ self.date: Optional[str] = data.get('date')
84
+ self.date_formatted: Optional[str] = None
85
+ if self.date:
86
+ try:
87
+ self.date_formatted = datetime.strptime(self.date, '%Y-%m-%d').strftime('%a, %b %d')
88
+ except ValueError:
89
+ pass
90
+
91
+ self.max_temp_c: Optional[str] = data.get('maxtempC')
92
+ self.max_temp_f: Optional[str] = data.get('maxtempF')
93
+ self.min_temp_c: Optional[str] = data.get('mintempC')
94
+ self.min_temp_f: Optional[str] = data.get('mintempF')
95
+ self.avg_temp_c: Optional[str] = data.get('avgtempC')
96
+ self.avg_temp_f: Optional[str] = data.get('avgtempF')
97
+ self.sun_hour: Optional[str] = data.get('sunHour')
98
+
99
+ # Parse astronomy data (simplified)
100
+ if data.get('astronomy') and len(data.get('astronomy', [])) > 0:
101
+ astro = data.get('astronomy', [{}])[0]
102
+ self.sunrise: Optional[str] = astro.get('sunrise')
103
+ self.sunset: Optional[str] = astro.get('sunset')
104
+ self.moon_phase: Optional[str] = astro.get('moon_phase')
105
+ else:
106
+ self.sunrise = self.sunset = self.moon_phase = None
107
+
108
+ # Parse hourly forecasts
109
+ self.hourly: List[HourlyForecast] = []
110
+ for hour_data in data.get('hourly', []):
111
+ self.hourly.append(HourlyForecast(hour_data))
112
+
113
+
114
+ class Weather:
115
+ """Weather response object with strongly typed properties."""
116
+
117
+ def __init__(self, data: Optional[Dict[str, Any]] = None) -> None:
118
+ """Initialize with weather data.
119
+
120
+ Args:
121
+ data: Weather data dictionary from wttr.in
122
+ """
123
+ if not data:
124
+ self.current_condition = None
125
+ self.location = None
126
+ self.forecast_days = []
127
+ return
128
+
129
+ # Parse current condition
130
+ self.current_condition: Optional[CurrentCondition] = None
131
+ if data.get('current_condition') and len(data.get('current_condition', [])) > 0:
132
+ self.current_condition = CurrentCondition(data.get('current_condition', [{}])[0])
133
+
134
+ # Parse location
135
+ self.location: Optional[Location] = None
136
+ if data.get('nearest_area') and len(data.get('nearest_area', [])) > 0:
137
+ self.location = Location(data.get('nearest_area', [{}])[0])
138
+
139
+ # Parse forecast days
140
+ self.forecast_days: List[DayForecast] = []
141
+ for day_data in data.get('weather', []):
142
+ self.forecast_days.append(DayForecast(day_data))
143
+
144
+ @property
145
+ def today(self) -> Optional[DayForecast]:
146
+ """Get today's forecast."""
147
+ return self.forecast_days[0] if self.forecast_days else None
148
+
149
+ @property
150
+ def tomorrow(self) -> Optional[DayForecast]:
151
+ """Get tomorrow's forecast."""
152
+ return self.forecast_days[1] if len(self.forecast_days) > 1 else None
153
+
154
+ @property
155
+ def summary(self) -> str:
156
+ """Get a simple text summary of current weather."""
157
+ if not self.current_condition or not self.location:
158
+ return "Weather data not available"
159
+
160
+ return f"{self.location.name}, {self.location.country}: {self.current_condition.weather_desc}, {self.current_condition.temp_c}°C ({self.current_condition.temp_f}°F)"
161
+
162
+
163
+ class WeatherClient:
164
+ """Client for fetching weather information."""
165
+
166
+ def get_weather(self, location: str) -> Weather:
167
+ """Get weather for the specified location.
168
+
169
+ Args:
170
+ location: Location to get weather for (city name, zip code, etc.)
171
+
172
+ Returns:
173
+ Weather object containing all weather data
174
+ """
175
+ try:
176
+ response = requests.get(f"https://wttr.in/{location}?format=j1", timeout=10)
177
+ response.raise_for_status()
178
+ return Weather(response.json())
179
+ except Exception as e:
180
+ print(f"Error fetching weather data: {str(e)}")
181
+ return Weather()
182
+
183
+
184
+ def get(location: str) -> Weather:
185
+ """Convenience function to get weather for a location.
186
+
187
+ Args:
188
+ location: Location to get weather for
189
+
190
+ Returns:
191
+ Weather object containing all weather data
192
+ """
193
+ client = WeatherClient()
194
+ return client.get_weather(location)
@@ -0,0 +1,76 @@
1
+ """
2
+ Weather ASCII art visualization module with a simple, strongly-typed API.
3
+
4
+ This module provides a clean interface for fetching weather information
5
+ in ASCII art format using the wttr.in service.
6
+ """
7
+
8
+ import requests
9
+ from typing import Dict, Optional, Any
10
+
11
+
12
+ class WeatherAscii:
13
+ """Container for ASCII weather data with a simple API."""
14
+
15
+ def __init__(self, content: str) -> None:
16
+ """Initialize with ASCII weather content.
17
+
18
+ Args:
19
+ content: ASCII weather data or error message
20
+ """
21
+ self._content = content
22
+
23
+ @property
24
+ def content(self) -> str:
25
+ """Get the ASCII content, similar to choices.message.content in OpenAI API."""
26
+ return self._content
27
+
28
+ def __str__(self) -> str:
29
+ """String representation of ASCII weather."""
30
+ return self.content
31
+
32
+
33
+ class WeatherAsciiClient:
34
+ """Client for fetching weather information in ASCII art."""
35
+
36
+ def get_weather(self, location: str, params: Optional[Dict[str, Any]] = None) -> WeatherAscii:
37
+ """Get ASCII weather for a location.
38
+
39
+ Args:
40
+ location: The location for which to fetch weather data
41
+ params: Additional parameters for the request
42
+
43
+ Returns:
44
+ WeatherAscii object containing ASCII art weather data
45
+ """
46
+ url = f"https://wttr.in/{location}"
47
+ headers = {'User-Agent': 'curl'}
48
+
49
+ try:
50
+ response = requests.get(url, headers=headers, params=params, timeout=10)
51
+ response.raise_for_status()
52
+
53
+ if response.status_code == 200:
54
+ # Remove the footer line from wttr.in
55
+ ascii_weather = "\n".join(response.text.splitlines()[:-1])
56
+ return WeatherAscii(ascii_weather)
57
+ else:
58
+ error_msg = f"Error: Unable to fetch weather data. Status code: {response.status_code}"
59
+ return WeatherAscii(error_msg)
60
+ except requests.exceptions.RequestException as e:
61
+ return WeatherAscii(f"Error: {str(e)}")
62
+
63
+
64
+ def get(location: str, params: Optional[Dict[str, Any]] = None) -> WeatherAscii:
65
+ """Convenience function to get ASCII weather for a location.
66
+
67
+ Args:
68
+ location: Location to get weather for
69
+ params: Additional parameters for the request
70
+
71
+ Returns:
72
+ WeatherAscii object containing ASCII art weather data
73
+ """
74
+ client = WeatherAsciiClient()
75
+ return client.get_weather(location, params)
76
+