webscout 8.2.2__py3-none-any.whl → 2026.1.19__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.
- webscout/AIauto.py +524 -143
- webscout/AIbase.py +247 -123
- webscout/AIutel.py +68 -132
- webscout/Bard.py +1072 -535
- webscout/Extra/GitToolkit/__init__.py +2 -2
- webscout/Extra/GitToolkit/gitapi/__init__.py +20 -12
- webscout/Extra/GitToolkit/gitapi/gist.py +142 -0
- webscout/Extra/GitToolkit/gitapi/organization.py +91 -0
- webscout/Extra/GitToolkit/gitapi/repository.py +308 -195
- webscout/Extra/GitToolkit/gitapi/search.py +162 -0
- webscout/Extra/GitToolkit/gitapi/trending.py +236 -0
- webscout/Extra/GitToolkit/gitapi/user.py +128 -96
- webscout/Extra/GitToolkit/gitapi/utils.py +82 -62
- webscout/Extra/YTToolkit/README.md +443 -0
- webscout/Extra/YTToolkit/YTdownloader.py +953 -957
- webscout/Extra/YTToolkit/__init__.py +3 -3
- webscout/Extra/YTToolkit/transcriber.py +595 -476
- webscout/Extra/YTToolkit/ytapi/README.md +230 -0
- webscout/Extra/YTToolkit/ytapi/__init__.py +22 -6
- webscout/Extra/YTToolkit/ytapi/captions.py +190 -0
- webscout/Extra/YTToolkit/ytapi/channel.py +302 -307
- webscout/Extra/YTToolkit/ytapi/errors.py +13 -13
- webscout/Extra/YTToolkit/ytapi/extras.py +178 -45
- webscout/Extra/YTToolkit/ytapi/hashtag.py +120 -0
- webscout/Extra/YTToolkit/ytapi/https.py +89 -88
- webscout/Extra/YTToolkit/ytapi/patterns.py +61 -61
- webscout/Extra/YTToolkit/ytapi/playlist.py +59 -59
- webscout/Extra/YTToolkit/ytapi/pool.py +8 -8
- webscout/Extra/YTToolkit/ytapi/query.py +143 -40
- webscout/Extra/YTToolkit/ytapi/shorts.py +122 -0
- webscout/Extra/YTToolkit/ytapi/stream.py +68 -63
- webscout/Extra/YTToolkit/ytapi/suggestions.py +97 -0
- webscout/Extra/YTToolkit/ytapi/utils.py +66 -62
- webscout/Extra/YTToolkit/ytapi/video.py +189 -18
- webscout/Extra/__init__.py +2 -3
- webscout/Extra/gguf.py +1298 -682
- webscout/Extra/tempmail/README.md +488 -0
- webscout/Extra/tempmail/__init__.py +28 -28
- webscout/Extra/tempmail/async_utils.py +143 -141
- webscout/Extra/tempmail/base.py +172 -161
- webscout/Extra/tempmail/cli.py +191 -187
- webscout/Extra/tempmail/emailnator.py +88 -84
- webscout/Extra/tempmail/mail_tm.py +378 -361
- webscout/Extra/tempmail/temp_mail_io.py +304 -292
- webscout/Extra/weather.py +196 -194
- webscout/Extra/weather_ascii.py +17 -15
- webscout/Provider/AISEARCH/PERPLEXED_search.py +175 -0
- webscout/Provider/AISEARCH/Perplexity.py +237 -304
- webscout/Provider/AISEARCH/README.md +106 -0
- webscout/Provider/AISEARCH/__init__.py +16 -10
- webscout/Provider/AISEARCH/brave_search.py +298 -0
- webscout/Provider/AISEARCH/iask_search.py +130 -209
- webscout/Provider/AISEARCH/monica_search.py +200 -246
- webscout/Provider/AISEARCH/webpilotai_search.py +242 -281
- webscout/Provider/Algion.py +413 -0
- webscout/Provider/Andi.py +74 -69
- webscout/Provider/Apriel.py +313 -0
- webscout/Provider/Ayle.py +323 -0
- webscout/Provider/ChatSandbox.py +329 -0
- webscout/Provider/ClaudeOnline.py +365 -0
- webscout/Provider/Cohere.py +232 -208
- webscout/Provider/DeepAI.py +367 -0
- webscout/Provider/Deepinfra.py +343 -173
- webscout/Provider/EssentialAI.py +217 -0
- webscout/Provider/ExaAI.py +274 -261
- webscout/Provider/Gemini.py +60 -54
- webscout/Provider/GithubChat.py +385 -367
- webscout/Provider/Gradient.py +286 -0
- webscout/Provider/Groq.py +556 -670
- webscout/Provider/HadadXYZ.py +323 -0
- webscout/Provider/HeckAI.py +392 -233
- webscout/Provider/HuggingFace.py +387 -0
- webscout/Provider/IBM.py +340 -0
- webscout/Provider/Jadve.py +317 -266
- webscout/Provider/K2Think.py +306 -0
- webscout/Provider/Koboldai.py +221 -381
- webscout/Provider/Netwrck.py +273 -228
- webscout/Provider/Nvidia.py +310 -0
- webscout/Provider/OPENAI/DeepAI.py +489 -0
- webscout/Provider/OPENAI/K2Think.py +423 -0
- webscout/Provider/OPENAI/PI.py +463 -0
- webscout/Provider/OPENAI/README.md +890 -0
- webscout/Provider/OPENAI/TogetherAI.py +405 -0
- webscout/Provider/OPENAI/TwoAI.py +255 -0
- webscout/Provider/OPENAI/__init__.py +148 -25
- webscout/Provider/OPENAI/ai4chat.py +348 -0
- webscout/Provider/OPENAI/akashgpt.py +436 -0
- webscout/Provider/OPENAI/algion.py +303 -0
- webscout/Provider/OPENAI/ayle.py +365 -0
- webscout/Provider/OPENAI/base.py +253 -46
- webscout/Provider/OPENAI/cerebras.py +296 -0
- webscout/Provider/OPENAI/chatgpt.py +514 -193
- webscout/Provider/OPENAI/chatsandbox.py +233 -0
- webscout/Provider/OPENAI/deepinfra.py +403 -272
- webscout/Provider/OPENAI/e2b.py +2370 -1350
- webscout/Provider/OPENAI/elmo.py +278 -0
- webscout/Provider/OPENAI/exaai.py +186 -138
- webscout/Provider/OPENAI/freeassist.py +446 -0
- webscout/Provider/OPENAI/gradient.py +448 -0
- webscout/Provider/OPENAI/groq.py +380 -0
- webscout/Provider/OPENAI/hadadxyz.py +292 -0
- webscout/Provider/OPENAI/heckai.py +100 -104
- webscout/Provider/OPENAI/huggingface.py +321 -0
- webscout/Provider/OPENAI/ibm.py +425 -0
- webscout/Provider/OPENAI/llmchat.py +253 -0
- webscout/Provider/OPENAI/llmchatco.py +378 -327
- webscout/Provider/OPENAI/meta.py +541 -0
- webscout/Provider/OPENAI/netwrck.py +110 -84
- webscout/Provider/OPENAI/nvidia.py +317 -0
- webscout/Provider/OPENAI/oivscode.py +348 -0
- webscout/Provider/OPENAI/openrouter.py +328 -0
- webscout/Provider/OPENAI/pydantic_imports.py +1 -0
- webscout/Provider/OPENAI/sambanova.py +397 -0
- webscout/Provider/OPENAI/sonus.py +126 -115
- webscout/Provider/OPENAI/textpollinations.py +218 -133
- webscout/Provider/OPENAI/toolbaz.py +136 -166
- webscout/Provider/OPENAI/typefully.py +419 -0
- webscout/Provider/OPENAI/typliai.py +279 -0
- webscout/Provider/OPENAI/utils.py +314 -211
- webscout/Provider/OPENAI/wisecat.py +103 -125
- webscout/Provider/OPENAI/writecream.py +185 -156
- webscout/Provider/OPENAI/x0gpt.py +227 -136
- webscout/Provider/OPENAI/zenmux.py +380 -0
- webscout/Provider/OpenRouter.py +386 -0
- webscout/Provider/Openai.py +337 -496
- webscout/Provider/PI.py +443 -344
- webscout/Provider/QwenLM.py +346 -254
- webscout/Provider/STT/__init__.py +28 -0
- webscout/Provider/STT/base.py +303 -0
- webscout/Provider/STT/elevenlabs.py +264 -0
- webscout/Provider/Sambanova.py +317 -0
- webscout/Provider/TTI/README.md +69 -0
- webscout/Provider/TTI/__init__.py +37 -12
- webscout/Provider/TTI/base.py +147 -0
- webscout/Provider/TTI/claudeonline.py +393 -0
- webscout/Provider/TTI/magicstudio.py +292 -0
- webscout/Provider/TTI/miragic.py +180 -0
- webscout/Provider/TTI/pollinations.py +331 -0
- webscout/Provider/TTI/together.py +334 -0
- webscout/Provider/TTI/utils.py +14 -0
- webscout/Provider/TTS/README.md +186 -0
- webscout/Provider/TTS/__init__.py +43 -7
- webscout/Provider/TTS/base.py +523 -0
- webscout/Provider/TTS/deepgram.py +286 -156
- webscout/Provider/TTS/elevenlabs.py +189 -111
- webscout/Provider/TTS/freetts.py +218 -0
- webscout/Provider/TTS/murfai.py +288 -113
- webscout/Provider/TTS/openai_fm.py +364 -0
- webscout/Provider/TTS/parler.py +203 -111
- webscout/Provider/TTS/qwen.py +334 -0
- webscout/Provider/TTS/sherpa.py +286 -0
- webscout/Provider/TTS/speechma.py +693 -180
- webscout/Provider/TTS/streamElements.py +275 -333
- webscout/Provider/TTS/utils.py +280 -280
- webscout/Provider/TextPollinationsAI.py +221 -121
- webscout/Provider/TogetherAI.py +450 -0
- webscout/Provider/TwoAI.py +309 -199
- webscout/Provider/TypliAI.py +311 -0
- webscout/Provider/UNFINISHED/ChatHub.py +219 -0
- webscout/Provider/{OPENAI/glider.py → UNFINISHED/ChutesAI.py} +160 -145
- webscout/Provider/UNFINISHED/GizAI.py +300 -0
- webscout/Provider/UNFINISHED/Marcus.py +218 -0
- webscout/Provider/UNFINISHED/Qodo.py +481 -0
- webscout/Provider/UNFINISHED/XenAI.py +330 -0
- webscout/Provider/{Youchat.py → UNFINISHED/Youchat.py} +64 -47
- webscout/Provider/UNFINISHED/aihumanizer.py +41 -0
- webscout/Provider/UNFINISHED/grammerchecker.py +37 -0
- webscout/Provider/UNFINISHED/liner.py +342 -0
- webscout/Provider/UNFINISHED/liner_api_request.py +246 -0
- webscout/Provider/UNFINISHED/samurai.py +231 -0
- webscout/Provider/WiseCat.py +256 -196
- webscout/Provider/WrDoChat.py +390 -0
- webscout/Provider/__init__.py +115 -198
- webscout/Provider/ai4chat.py +181 -202
- webscout/Provider/akashgpt.py +330 -342
- webscout/Provider/cerebras.py +397 -242
- webscout/Provider/cleeai.py +236 -213
- webscout/Provider/elmo.py +291 -234
- webscout/Provider/geminiapi.py +343 -208
- webscout/Provider/julius.py +245 -223
- webscout/Provider/learnfastai.py +333 -266
- webscout/Provider/llama3mitril.py +230 -180
- webscout/Provider/llmchat.py +308 -213
- webscout/Provider/llmchatco.py +321 -311
- webscout/Provider/meta.py +996 -794
- webscout/Provider/oivscode.py +332 -0
- webscout/Provider/searchchat.py +316 -293
- webscout/Provider/sonus.py +264 -208
- webscout/Provider/toolbaz.py +359 -320
- webscout/Provider/turboseek.py +332 -219
- webscout/Provider/typefully.py +262 -280
- webscout/Provider/x0gpt.py +332 -256
- webscout/__init__.py +31 -38
- webscout/__main__.py +5 -5
- webscout/cli.py +585 -293
- webscout/client.py +1497 -0
- webscout/conversation.py +140 -565
- webscout/exceptions.py +383 -339
- webscout/litagent/__init__.py +29 -29
- webscout/litagent/agent.py +492 -455
- webscout/litagent/constants.py +60 -60
- webscout/models.py +505 -181
- webscout/optimizers.py +32 -378
- webscout/prompt_manager.py +376 -274
- webscout/sanitize.py +1514 -0
- webscout/scout/README.md +452 -0
- webscout/scout/__init__.py +8 -8
- webscout/scout/core/__init__.py +7 -7
- webscout/scout/core/crawler.py +330 -140
- webscout/scout/core/scout.py +800 -568
- webscout/scout/core/search_result.py +51 -96
- webscout/scout/core/text_analyzer.py +64 -63
- webscout/scout/core/text_utils.py +412 -277
- webscout/scout/core/web_analyzer.py +54 -52
- webscout/scout/element.py +872 -460
- webscout/scout/parsers/__init__.py +70 -69
- webscout/scout/parsers/html5lib_parser.py +182 -172
- webscout/scout/parsers/html_parser.py +238 -236
- webscout/scout/parsers/lxml_parser.py +203 -178
- webscout/scout/utils.py +38 -37
- webscout/search/__init__.py +47 -0
- webscout/search/base.py +201 -0
- webscout/search/bing_main.py +45 -0
- webscout/search/brave_main.py +92 -0
- webscout/search/duckduckgo_main.py +57 -0
- webscout/search/engines/__init__.py +127 -0
- webscout/search/engines/bing/__init__.py +15 -0
- webscout/search/engines/bing/base.py +35 -0
- webscout/search/engines/bing/images.py +114 -0
- webscout/search/engines/bing/news.py +96 -0
- webscout/search/engines/bing/suggestions.py +36 -0
- webscout/search/engines/bing/text.py +109 -0
- webscout/search/engines/brave/__init__.py +19 -0
- webscout/search/engines/brave/base.py +47 -0
- webscout/search/engines/brave/images.py +213 -0
- webscout/search/engines/brave/news.py +353 -0
- webscout/search/engines/brave/suggestions.py +318 -0
- webscout/search/engines/brave/text.py +167 -0
- webscout/search/engines/brave/videos.py +364 -0
- webscout/search/engines/duckduckgo/__init__.py +25 -0
- webscout/search/engines/duckduckgo/answers.py +80 -0
- webscout/search/engines/duckduckgo/base.py +189 -0
- webscout/search/engines/duckduckgo/images.py +100 -0
- webscout/search/engines/duckduckgo/maps.py +183 -0
- webscout/search/engines/duckduckgo/news.py +70 -0
- webscout/search/engines/duckduckgo/suggestions.py +22 -0
- webscout/search/engines/duckduckgo/text.py +221 -0
- webscout/search/engines/duckduckgo/translate.py +48 -0
- webscout/search/engines/duckduckgo/videos.py +80 -0
- webscout/search/engines/duckduckgo/weather.py +84 -0
- webscout/search/engines/mojeek.py +61 -0
- webscout/search/engines/wikipedia.py +77 -0
- webscout/search/engines/yahoo/__init__.py +41 -0
- webscout/search/engines/yahoo/answers.py +19 -0
- webscout/search/engines/yahoo/base.py +34 -0
- webscout/search/engines/yahoo/images.py +323 -0
- webscout/search/engines/yahoo/maps.py +19 -0
- webscout/search/engines/yahoo/news.py +258 -0
- webscout/search/engines/yahoo/suggestions.py +140 -0
- webscout/search/engines/yahoo/text.py +273 -0
- webscout/search/engines/yahoo/translate.py +19 -0
- webscout/search/engines/yahoo/videos.py +302 -0
- webscout/search/engines/yahoo/weather.py +220 -0
- webscout/search/engines/yandex.py +67 -0
- webscout/search/engines/yep/__init__.py +13 -0
- webscout/search/engines/yep/base.py +34 -0
- webscout/search/engines/yep/images.py +101 -0
- webscout/search/engines/yep/suggestions.py +38 -0
- webscout/search/engines/yep/text.py +99 -0
- webscout/search/http_client.py +172 -0
- webscout/search/results.py +141 -0
- webscout/search/yahoo_main.py +57 -0
- webscout/search/yep_main.py +48 -0
- webscout/server/__init__.py +48 -0
- webscout/server/config.py +78 -0
- webscout/server/exceptions.py +69 -0
- webscout/server/providers.py +286 -0
- webscout/server/request_models.py +131 -0
- webscout/server/request_processing.py +404 -0
- webscout/server/routes.py +642 -0
- webscout/server/server.py +351 -0
- webscout/server/ui_templates.py +1171 -0
- webscout/swiftcli/__init__.py +79 -809
- webscout/swiftcli/core/__init__.py +7 -0
- webscout/swiftcli/core/cli.py +574 -0
- webscout/swiftcli/core/context.py +98 -0
- webscout/swiftcli/core/group.py +268 -0
- webscout/swiftcli/decorators/__init__.py +28 -0
- webscout/swiftcli/decorators/command.py +243 -0
- webscout/swiftcli/decorators/options.py +247 -0
- webscout/swiftcli/decorators/output.py +392 -0
- webscout/swiftcli/exceptions.py +21 -0
- webscout/swiftcli/plugins/__init__.py +9 -0
- webscout/swiftcli/plugins/base.py +134 -0
- webscout/swiftcli/plugins/manager.py +269 -0
- webscout/swiftcli/utils/__init__.py +58 -0
- webscout/swiftcli/utils/formatting.py +251 -0
- webscout/swiftcli/utils/parsing.py +368 -0
- webscout/update_checker.py +280 -136
- webscout/utils.py +28 -14
- webscout/version.py +2 -1
- webscout/version.py.bak +3 -0
- webscout/zeroart/__init__.py +218 -55
- webscout/zeroart/base.py +70 -60
- webscout/zeroart/effects.py +155 -99
- webscout/zeroart/fonts.py +1799 -816
- webscout-2026.1.19.dist-info/METADATA +638 -0
- webscout-2026.1.19.dist-info/RECORD +312 -0
- {webscout-8.2.2.dist-info → webscout-2026.1.19.dist-info}/WHEEL +1 -1
- webscout-2026.1.19.dist-info/entry_points.txt +4 -0
- webscout-2026.1.19.dist-info/top_level.txt +1 -0
- inferno/__init__.py +0 -6
- inferno/__main__.py +0 -9
- inferno/cli.py +0 -6
- webscout/DWEBS.py +0 -477
- webscout/Extra/autocoder/__init__.py +0 -9
- webscout/Extra/autocoder/autocoder.py +0 -849
- webscout/Extra/autocoder/autocoder_utiles.py +0 -332
- webscout/LLM.py +0 -442
- webscout/Litlogger/__init__.py +0 -67
- webscout/Litlogger/core/__init__.py +0 -6
- webscout/Litlogger/core/level.py +0 -23
- webscout/Litlogger/core/logger.py +0 -165
- webscout/Litlogger/handlers/__init__.py +0 -12
- webscout/Litlogger/handlers/console.py +0 -33
- webscout/Litlogger/handlers/file.py +0 -143
- webscout/Litlogger/handlers/network.py +0 -173
- webscout/Litlogger/styles/__init__.py +0 -7
- webscout/Litlogger/styles/colors.py +0 -249
- webscout/Litlogger/styles/formats.py +0 -458
- webscout/Litlogger/styles/text.py +0 -87
- webscout/Litlogger/utils/__init__.py +0 -6
- webscout/Litlogger/utils/detectors.py +0 -153
- webscout/Litlogger/utils/formatters.py +0 -200
- webscout/Local/__init__.py +0 -12
- webscout/Local/__main__.py +0 -9
- webscout/Local/api.py +0 -576
- webscout/Local/cli.py +0 -516
- webscout/Local/config.py +0 -75
- webscout/Local/llm.py +0 -287
- webscout/Local/model_manager.py +0 -253
- webscout/Local/server.py +0 -721
- webscout/Local/utils.py +0 -93
- webscout/Provider/AI21.py +0 -177
- webscout/Provider/AISEARCH/DeepFind.py +0 -250
- webscout/Provider/AISEARCH/ISou.py +0 -256
- webscout/Provider/AISEARCH/felo_search.py +0 -228
- webscout/Provider/AISEARCH/genspark_search.py +0 -208
- webscout/Provider/AISEARCH/hika_search.py +0 -194
- webscout/Provider/AISEARCH/scira_search.py +0 -324
- webscout/Provider/Aitopia.py +0 -292
- webscout/Provider/AllenAI.py +0 -413
- webscout/Provider/Blackboxai.py +0 -229
- webscout/Provider/C4ai.py +0 -432
- webscout/Provider/ChatGPTClone.py +0 -226
- webscout/Provider/ChatGPTES.py +0 -237
- webscout/Provider/ChatGPTGratis.py +0 -194
- webscout/Provider/Chatify.py +0 -175
- webscout/Provider/Cloudflare.py +0 -273
- webscout/Provider/DeepSeek.py +0 -196
- webscout/Provider/ElectronHub.py +0 -709
- webscout/Provider/ExaChat.py +0 -342
- webscout/Provider/Free2GPT.py +0 -241
- webscout/Provider/GPTWeb.py +0 -193
- webscout/Provider/Glider.py +0 -211
- webscout/Provider/HF_space/__init__.py +0 -0
- webscout/Provider/HF_space/qwen_qwen2.py +0 -206
- webscout/Provider/HuggingFaceChat.py +0 -462
- webscout/Provider/Hunyuan.py +0 -272
- webscout/Provider/LambdaChat.py +0 -392
- webscout/Provider/Llama.py +0 -200
- webscout/Provider/Llama3.py +0 -204
- webscout/Provider/Marcus.py +0 -148
- webscout/Provider/OLLAMA.py +0 -396
- webscout/Provider/OPENAI/c4ai.py +0 -367
- webscout/Provider/OPENAI/chatgptclone.py +0 -460
- webscout/Provider/OPENAI/exachat.py +0 -433
- webscout/Provider/OPENAI/freeaichat.py +0 -352
- webscout/Provider/OPENAI/opkfc.py +0 -488
- webscout/Provider/OPENAI/scirachat.py +0 -463
- webscout/Provider/OPENAI/standardinput.py +0 -425
- webscout/Provider/OPENAI/typegpt.py +0 -346
- webscout/Provider/OPENAI/uncovrAI.py +0 -455
- webscout/Provider/OPENAI/venice.py +0 -413
- webscout/Provider/OPENAI/yep.py +0 -327
- webscout/Provider/OpenGPT.py +0 -199
- webscout/Provider/Perplexitylabs.py +0 -415
- webscout/Provider/Phind.py +0 -535
- webscout/Provider/PizzaGPT.py +0 -198
- webscout/Provider/Reka.py +0 -214
- webscout/Provider/StandardInput.py +0 -278
- webscout/Provider/TTI/AiForce/__init__.py +0 -22
- webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
- webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
- webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
- webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
- webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
- webscout/Provider/TTI/ImgSys/__init__.py +0 -23
- webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
- webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
- webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
- webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
- webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
- webscout/Provider/TTI/Nexra/__init__.py +0 -22
- webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
- webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
- webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
- webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
- webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
- webscout/Provider/TTI/aiarta/__init__.py +0 -2
- webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
- webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
- webscout/Provider/TTI/artbit/__init__.py +0 -22
- webscout/Provider/TTI/artbit/async_artbit.py +0 -155
- webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
- webscout/Provider/TTI/fastflux/__init__.py +0 -22
- webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
- webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
- webscout/Provider/TTI/huggingface/__init__.py +0 -22
- webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
- webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
- webscout/Provider/TTI/piclumen/__init__.py +0 -23
- webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
- webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
- webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
- webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
- webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
- webscout/Provider/TTI/talkai/__init__.py +0 -4
- webscout/Provider/TTI/talkai/async_talkai.py +0 -229
- webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
- webscout/Provider/TTS/gesserit.py +0 -127
- webscout/Provider/TeachAnything.py +0 -187
- webscout/Provider/Venice.py +0 -219
- webscout/Provider/VercelAI.py +0 -234
- webscout/Provider/WebSim.py +0 -228
- webscout/Provider/Writecream.py +0 -211
- webscout/Provider/WritingMate.py +0 -197
- webscout/Provider/aimathgpt.py +0 -189
- webscout/Provider/askmyai.py +0 -158
- webscout/Provider/asksteve.py +0 -203
- webscout/Provider/bagoodex.py +0 -145
- webscout/Provider/chatglm.py +0 -205
- webscout/Provider/copilot.py +0 -428
- webscout/Provider/freeaichat.py +0 -271
- webscout/Provider/gaurish.py +0 -244
- webscout/Provider/geminiprorealtime.py +0 -160
- webscout/Provider/granite.py +0 -187
- webscout/Provider/hermes.py +0 -219
- webscout/Provider/koala.py +0 -268
- webscout/Provider/labyrinth.py +0 -340
- webscout/Provider/lepton.py +0 -194
- webscout/Provider/llamatutor.py +0 -192
- webscout/Provider/multichat.py +0 -325
- webscout/Provider/promptrefine.py +0 -193
- webscout/Provider/scira_chat.py +0 -277
- webscout/Provider/scnet.py +0 -187
- webscout/Provider/talkai.py +0 -194
- webscout/Provider/tutorai.py +0 -252
- webscout/Provider/typegpt.py +0 -232
- webscout/Provider/uncovr.py +0 -312
- webscout/Provider/yep.py +0 -376
- webscout/litprinter/__init__.py +0 -59
- webscout/scout/core.py +0 -881
- webscout/tempid.py +0 -128
- webscout/webscout_search.py +0 -1346
- webscout/webscout_search_async.py +0 -877
- webscout/yep_search.py +0 -297
- webscout-8.2.2.dist-info/METADATA +0 -734
- webscout-8.2.2.dist-info/RECORD +0 -309
- webscout-8.2.2.dist-info/entry_points.txt +0 -5
- webscout-8.2.2.dist-info/top_level.txt +0 -3
- webstoken/__init__.py +0 -30
- webstoken/classifier.py +0 -189
- webstoken/keywords.py +0 -216
- webstoken/language.py +0 -128
- webstoken/ner.py +0 -164
- webstoken/normalizer.py +0 -35
- webstoken/processor.py +0 -77
- webstoken/sentiment.py +0 -206
- webstoken/stemmer.py +0 -73
- webstoken/tagger.py +0 -60
- webstoken/tokenizer.py +0 -158
- {webscout-8.2.2.dist-info → webscout-2026.1.19.dist-info/licenses}/LICENSE.md +0 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import random
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
|
|
5
|
+
import requests
|
|
6
|
+
|
|
7
|
+
from webscout.AIbase import SimpleModelList
|
|
8
|
+
from webscout.litagent import LitAgent
|
|
9
|
+
from webscout.Provider.TTI.base import BaseImages, TTICompatibleProvider
|
|
10
|
+
from webscout.Provider.TTI.utils import ImageData, ImageResponse
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Images(BaseImages):
|
|
14
|
+
"""Handles image generation requests for the Miragic AI provider."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, client: "MiragicAI"):
|
|
17
|
+
self._client = client
|
|
18
|
+
|
|
19
|
+
def create(
|
|
20
|
+
self,
|
|
21
|
+
*,
|
|
22
|
+
model: str = "flux",
|
|
23
|
+
prompt: str,
|
|
24
|
+
n: int = 1,
|
|
25
|
+
size: str = "1024x1024",
|
|
26
|
+
response_format: str = "url",
|
|
27
|
+
user: Optional[str] = None,
|
|
28
|
+
style: str = "none",
|
|
29
|
+
aspect_ratio: str = "1:1",
|
|
30
|
+
timeout: Optional[int] = None,
|
|
31
|
+
image_format: str = "png",
|
|
32
|
+
seed: Optional[int] = None,
|
|
33
|
+
**kwargs,
|
|
34
|
+
) -> ImageResponse:
|
|
35
|
+
"""
|
|
36
|
+
Creates images using the Miragic AI API.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
model (str): The model to use. Options: "flux", "turbo", "gptimage". Defaults to "flux".
|
|
40
|
+
prompt (str): The text description of the image to generate.
|
|
41
|
+
n (int): Number of images to generate. Defaults to 1.
|
|
42
|
+
size (str): Image dimensions in "WxH" format. Defaults to "1024x1024".
|
|
43
|
+
response_format (str): Format of the response ("url" or "b64_json"). Defaults to "url".
|
|
44
|
+
user (Optional[str]): Optional user identifier.
|
|
45
|
+
style (str): Optional style parameter.
|
|
46
|
+
aspect_ratio (str): Optional aspect ratio parameter.
|
|
47
|
+
timeout (Optional[int]): Request timeout in seconds. Defaults to 60.
|
|
48
|
+
image_format (str): Output image format ("png" or "jpeg"). Defaults to "png".
|
|
49
|
+
seed (Optional[int]): Random seed for reproducibility.
|
|
50
|
+
**kwargs: Additional parameters:
|
|
51
|
+
- enhance_prompt (bool): Use AI to enhance the prompt.
|
|
52
|
+
- safe_filter (bool): Enable strict NSFW filtering.
|
|
53
|
+
- image_url (str): Source image URL for image-to-image models.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
ImageResponse: Object containing the generated image data.
|
|
57
|
+
|
|
58
|
+
Raises:
|
|
59
|
+
RuntimeError: If image generation or retrieval fails.
|
|
60
|
+
"""
|
|
61
|
+
# Use default timeout if not provided
|
|
62
|
+
effective_timeout = timeout if timeout is not None else 60
|
|
63
|
+
|
|
64
|
+
width, height = 1024, 1024
|
|
65
|
+
if size:
|
|
66
|
+
try:
|
|
67
|
+
parts = size.split("x")
|
|
68
|
+
if len(parts) == 2:
|
|
69
|
+
width, height = int(parts[0]), int(parts[1])
|
|
70
|
+
except ValueError:
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
width = max(256, min(2048, width))
|
|
74
|
+
height = max(256, min(2048, height))
|
|
75
|
+
|
|
76
|
+
enhance = kwargs.get("enhance_prompt", False)
|
|
77
|
+
safe = kwargs.get("safe_filter", False)
|
|
78
|
+
image_url = kwargs.get("image_url")
|
|
79
|
+
|
|
80
|
+
images_data = []
|
|
81
|
+
|
|
82
|
+
for _ in range(n):
|
|
83
|
+
current_seed = seed if seed is not None else random.randint(0, 2**32 - 1)
|
|
84
|
+
|
|
85
|
+
payload = {
|
|
86
|
+
"data": [prompt, model, width, height, current_seed, image_url, enhance, safe]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
post_url = f"{self._client.api_endpoint}/call/generate_image_via_api_secure"
|
|
91
|
+
resp = self._client.session.post(post_url, json=payload, timeout=effective_timeout)
|
|
92
|
+
resp.raise_for_status()
|
|
93
|
+
|
|
94
|
+
event_id = resp.json().get("event_id")
|
|
95
|
+
if not event_id:
|
|
96
|
+
raise RuntimeError(f"Failed to obtain event_id: {resp.text}")
|
|
97
|
+
|
|
98
|
+
stream_url = (
|
|
99
|
+
f"{self._client.api_endpoint}/call/generate_image_via_api_secure/{event_id}"
|
|
100
|
+
)
|
|
101
|
+
image_url_result = None
|
|
102
|
+
|
|
103
|
+
with self._client.session.get(
|
|
104
|
+
stream_url, stream=True, timeout=effective_timeout + 60
|
|
105
|
+
) as stream_resp:
|
|
106
|
+
stream_resp.raise_for_status()
|
|
107
|
+
for line in stream_resp.iter_lines():
|
|
108
|
+
if not line:
|
|
109
|
+
continue
|
|
110
|
+
line_text = line.decode("utf-8")
|
|
111
|
+
|
|
112
|
+
if line_text.startswith("data: "):
|
|
113
|
+
data_str = line_text[6:]
|
|
114
|
+
try:
|
|
115
|
+
data_json = json.loads(data_str)
|
|
116
|
+
if isinstance(data_json, list) and len(data_json) > 0:
|
|
117
|
+
result_item = data_json[0]
|
|
118
|
+
if isinstance(result_item, dict):
|
|
119
|
+
image_url_result = result_item.get("url")
|
|
120
|
+
except json.JSONDecodeError:
|
|
121
|
+
continue
|
|
122
|
+
except Exception as e:
|
|
123
|
+
raise RuntimeError(f"Image generation failed: {e}")
|
|
124
|
+
|
|
125
|
+
if image_url_result:
|
|
126
|
+
images_data.append(ImageData(url=image_url_result))
|
|
127
|
+
else:
|
|
128
|
+
raise RuntimeError("Failed to retrieve image URL from the response stream.")
|
|
129
|
+
|
|
130
|
+
return ImageResponse(data=images_data)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class MiragicAI(TTICompatibleProvider):
|
|
134
|
+
"""
|
|
135
|
+
Miragic AI TTI Provider implementation.
|
|
136
|
+
|
|
137
|
+
Reverse engineered from the Hugging Face Space:
|
|
138
|
+
https://huggingface.co/spaces/Miragic-AI/Miragic-AI-Image-Generator
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
required_auth: bool = False
|
|
142
|
+
working: bool = True
|
|
143
|
+
AVAILABLE_MODELS = ["flux", "turbo", "gptimage"]
|
|
144
|
+
|
|
145
|
+
def __init__(self, **kwargs: Any):
|
|
146
|
+
"""Initializes the MiragicAI provider with a persistent session."""
|
|
147
|
+
self.api_endpoint = "https://miragic-ai-miragic-ai-image-generator.hf.space/gradio_api"
|
|
148
|
+
self.session = requests.Session()
|
|
149
|
+
self.session.headers.update(
|
|
150
|
+
{
|
|
151
|
+
"User-Agent": LitAgent().random(),
|
|
152
|
+
"Referer": "https://miragic-ai-miragic-ai-image-generator.hf.space/",
|
|
153
|
+
"Origin": "https://miragic-ai-miragic-ai-image-generator.hf.space",
|
|
154
|
+
"Content-Type": "application/json",
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
self.images = Images(self)
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def models(self) -> SimpleModelList:
|
|
161
|
+
return SimpleModelList(type(self).AVAILABLE_MODELS)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
if __name__ == "__main__":
|
|
165
|
+
from rich import print
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
client = MiragicAI()
|
|
169
|
+
print(f"Available Models: {client.models.list()}")
|
|
170
|
+
|
|
171
|
+
print("Generating sample image...")
|
|
172
|
+
response = client.images.create(
|
|
173
|
+
prompt="A serene landscape with a lake and mountains, oil painting style",
|
|
174
|
+
model="flux",
|
|
175
|
+
size="1024x1024",
|
|
176
|
+
)
|
|
177
|
+
print(response)
|
|
178
|
+
|
|
179
|
+
except Exception as error:
|
|
180
|
+
print(f"Error during execution: {error}")
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import random
|
|
5
|
+
import tempfile
|
|
6
|
+
import time
|
|
7
|
+
from io import BytesIO
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
9
|
+
|
|
10
|
+
import requests
|
|
11
|
+
from requests.exceptions import RequestException
|
|
12
|
+
|
|
13
|
+
from webscout.AIbase import SimpleModelList
|
|
14
|
+
from webscout.litagent import LitAgent
|
|
15
|
+
from webscout.Provider.TTI.base import BaseImages, TTICompatibleProvider
|
|
16
|
+
from webscout.Provider.TTI.utils import ImageData, ImageResponse
|
|
17
|
+
|
|
18
|
+
# Optional Pillow import for image format conversion
|
|
19
|
+
Image: Any = None
|
|
20
|
+
PILLOW_AVAILABLE = False
|
|
21
|
+
try:
|
|
22
|
+
from PIL import Image
|
|
23
|
+
|
|
24
|
+
PILLOW_AVAILABLE = True
|
|
25
|
+
except ImportError:
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from PIL import Image as PILImage
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _convert_image_format(img_bytes: bytes, target_format: str) -> bytes:
|
|
33
|
+
"""
|
|
34
|
+
Convert image bytes to the specified format using Pillow.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
img_bytes: Raw image bytes
|
|
38
|
+
target_format: Target format ('png' or 'jpeg')
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Converted image bytes
|
|
42
|
+
|
|
43
|
+
Raises:
|
|
44
|
+
ImportError: If Pillow is not installed
|
|
45
|
+
"""
|
|
46
|
+
if not PILLOW_AVAILABLE or Image is None:
|
|
47
|
+
raise ImportError(
|
|
48
|
+
"Pillow (PIL) is required for image format conversion. "
|
|
49
|
+
"Install it with: pip install pillow"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
with BytesIO(img_bytes) as input_io:
|
|
53
|
+
with Image.open(input_io) as im:
|
|
54
|
+
out_io = BytesIO()
|
|
55
|
+
if target_format.lower() == "jpeg":
|
|
56
|
+
im = im.convert("RGB")
|
|
57
|
+
im.save(out_io, format="JPEG")
|
|
58
|
+
else:
|
|
59
|
+
im.save(out_io, format="PNG")
|
|
60
|
+
return out_io.getvalue()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _detect_image_format(img_bytes: bytes) -> Optional[str]:
|
|
64
|
+
"""
|
|
65
|
+
Detect image format from magic bytes.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
img_bytes: Raw image bytes
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Format string ('png', 'jpeg', 'gif', 'webp') or None if unknown
|
|
72
|
+
"""
|
|
73
|
+
if len(img_bytes) < 12:
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
# PNG: 89 50 4E 47 0D 0A 1A 0A
|
|
77
|
+
if img_bytes[:8] == b"\x89PNG\r\n\x1a\n":
|
|
78
|
+
return "png"
|
|
79
|
+
|
|
80
|
+
# JPEG: FF D8 FF
|
|
81
|
+
if img_bytes[:3] == b"\xff\xd8\xff":
|
|
82
|
+
return "jpeg"
|
|
83
|
+
|
|
84
|
+
# GIF: GIF87a or GIF89a
|
|
85
|
+
if img_bytes[:6] in (b"GIF87a", b"GIF89a"):
|
|
86
|
+
return "gif"
|
|
87
|
+
|
|
88
|
+
# WebP: RIFF....WEBP
|
|
89
|
+
if img_bytes[:4] == b"RIFF" and img_bytes[8:12] == b"WEBP":
|
|
90
|
+
return "webp"
|
|
91
|
+
|
|
92
|
+
return None
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class Images(BaseImages):
|
|
96
|
+
def __init__(self, client: "PollinationsAI"):
|
|
97
|
+
self._client = client
|
|
98
|
+
|
|
99
|
+
def create(
|
|
100
|
+
self,
|
|
101
|
+
*,
|
|
102
|
+
model: str,
|
|
103
|
+
prompt: str,
|
|
104
|
+
n: int = 1,
|
|
105
|
+
size: str = "1024x1024",
|
|
106
|
+
response_format: str = "url",
|
|
107
|
+
user: Optional[str] = None,
|
|
108
|
+
style: str = "none",
|
|
109
|
+
aspect_ratio: str = "1:1",
|
|
110
|
+
timeout: Optional[int] = None,
|
|
111
|
+
image_format: str = "png",
|
|
112
|
+
seed: Optional[int] = None,
|
|
113
|
+
convert_format: bool = False,
|
|
114
|
+
**kwargs,
|
|
115
|
+
) -> ImageResponse:
|
|
116
|
+
"""
|
|
117
|
+
Generate images using Pollinations API.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
model: Model to use for generation
|
|
121
|
+
prompt: The image generation prompt
|
|
122
|
+
n: Number of images to generate
|
|
123
|
+
size: Image size (e.g., "1024x1024")
|
|
124
|
+
response_format: "url" or "b64_json"
|
|
125
|
+
user: Optional user identifier
|
|
126
|
+
style: Style parameter
|
|
127
|
+
aspect_ratio: Aspect ratio
|
|
128
|
+
timeout: Request timeout in seconds (default: 60)
|
|
129
|
+
image_format: Output format "png" or "jpeg" (used for upload filename)
|
|
130
|
+
seed: Optional random seed for reproducibility
|
|
131
|
+
convert_format: If True, convert image to specified format (requires Pillow)
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
ImageResponse with generated image data
|
|
135
|
+
"""
|
|
136
|
+
# Use default timeout if not provided
|
|
137
|
+
effective_timeout = timeout if timeout is not None else 60
|
|
138
|
+
|
|
139
|
+
images = []
|
|
140
|
+
urls = []
|
|
141
|
+
|
|
142
|
+
def upload_file_with_retry(img_bytes: bytes, image_format: str, max_retries: int = 3):
|
|
143
|
+
ext = "jpg" if image_format.lower() == "jpeg" else image_format.lower()
|
|
144
|
+
if ext not in ("jpg", "png", "gif", "webp"):
|
|
145
|
+
ext = "png"
|
|
146
|
+
for attempt in range(max_retries):
|
|
147
|
+
tmp_path = None
|
|
148
|
+
try:
|
|
149
|
+
with tempfile.NamedTemporaryFile(suffix=f".{ext}", delete=False) as tmp:
|
|
150
|
+
tmp.write(img_bytes)
|
|
151
|
+
tmp.flush()
|
|
152
|
+
tmp_path = tmp.name
|
|
153
|
+
with open(tmp_path, "rb") as f:
|
|
154
|
+
files = {"fileToUpload": (f"image.{ext}", f, f"image/{ext}")}
|
|
155
|
+
data = {"reqtype": "fileupload", "json": "true"}
|
|
156
|
+
headers = {"User-Agent": LitAgent().random()}
|
|
157
|
+
if attempt > 0:
|
|
158
|
+
headers["Connection"] = "close"
|
|
159
|
+
resp = requests.post(
|
|
160
|
+
"https://catbox.moe/user/api.php",
|
|
161
|
+
files=files,
|
|
162
|
+
data=data,
|
|
163
|
+
headers=headers,
|
|
164
|
+
timeout=effective_timeout,
|
|
165
|
+
)
|
|
166
|
+
if resp.status_code == 200 and resp.text.strip():
|
|
167
|
+
text = resp.text.strip()
|
|
168
|
+
if text.startswith("http"):
|
|
169
|
+
return text
|
|
170
|
+
try:
|
|
171
|
+
result = resp.json()
|
|
172
|
+
if "url" in result:
|
|
173
|
+
return result["url"]
|
|
174
|
+
except json.JSONDecodeError:
|
|
175
|
+
if "http" in text:
|
|
176
|
+
return text
|
|
177
|
+
except Exception:
|
|
178
|
+
if attempt < max_retries - 1:
|
|
179
|
+
time.sleep(1 * (attempt + 1))
|
|
180
|
+
finally:
|
|
181
|
+
if tmp_path and os.path.isfile(tmp_path):
|
|
182
|
+
try:
|
|
183
|
+
os.remove(tmp_path)
|
|
184
|
+
except Exception:
|
|
185
|
+
pass
|
|
186
|
+
return None
|
|
187
|
+
|
|
188
|
+
def upload_file_alternative(img_bytes: bytes, image_format: str):
|
|
189
|
+
try:
|
|
190
|
+
ext = "jpg" if image_format.lower() == "jpeg" else image_format.lower()
|
|
191
|
+
if ext not in ("jpg", "png", "gif", "webp"):
|
|
192
|
+
ext = "png"
|
|
193
|
+
with tempfile.NamedTemporaryFile(suffix=f".{ext}", delete=False) as tmp:
|
|
194
|
+
tmp.write(img_bytes)
|
|
195
|
+
tmp.flush()
|
|
196
|
+
tmp_path = tmp.name
|
|
197
|
+
try:
|
|
198
|
+
if not os.path.isfile(tmp_path):
|
|
199
|
+
return None
|
|
200
|
+
with open(tmp_path, "rb") as img_file:
|
|
201
|
+
files = {"file": img_file}
|
|
202
|
+
response = requests.post(
|
|
203
|
+
"https://0x0.st", files=files, timeout=effective_timeout
|
|
204
|
+
)
|
|
205
|
+
response.raise_for_status()
|
|
206
|
+
image_url = response.text.strip()
|
|
207
|
+
if not image_url.startswith("http"):
|
|
208
|
+
return None
|
|
209
|
+
return image_url
|
|
210
|
+
except Exception:
|
|
211
|
+
return None
|
|
212
|
+
finally:
|
|
213
|
+
try:
|
|
214
|
+
os.remove(tmp_path)
|
|
215
|
+
except Exception:
|
|
216
|
+
pass
|
|
217
|
+
except Exception:
|
|
218
|
+
return None
|
|
219
|
+
|
|
220
|
+
for i in range(n):
|
|
221
|
+
# Prepare parameters for Pollinations API
|
|
222
|
+
params = {
|
|
223
|
+
"model": model,
|
|
224
|
+
"width": int(size.split("x")[0]) if "x" in size else 1024,
|
|
225
|
+
"height": int(size.split("x")[1]) if "x" in size else 1024,
|
|
226
|
+
"seed": seed if seed is not None else random.randint(0, 2**32 - 1),
|
|
227
|
+
}
|
|
228
|
+
# Build the API URL
|
|
229
|
+
base_url = f"https://image.pollinations.ai/prompt/{prompt}"
|
|
230
|
+
# Compose query string
|
|
231
|
+
query = "&".join(f"{k}={v}" for k, v in params.items())
|
|
232
|
+
url = f"{base_url}?{query}"
|
|
233
|
+
try:
|
|
234
|
+
resp = self._client.session.get(
|
|
235
|
+
url,
|
|
236
|
+
timeout=effective_timeout,
|
|
237
|
+
)
|
|
238
|
+
resp.raise_for_status()
|
|
239
|
+
img_bytes = resp.content
|
|
240
|
+
except RequestException as e:
|
|
241
|
+
raise RuntimeError(f"Failed to fetch image from Pollinations API: {e}")
|
|
242
|
+
|
|
243
|
+
# Convert image format if requested
|
|
244
|
+
if convert_format:
|
|
245
|
+
img_bytes = _convert_image_format(img_bytes, image_format)
|
|
246
|
+
actual_format = image_format
|
|
247
|
+
else:
|
|
248
|
+
# Detect actual image format from bytes
|
|
249
|
+
actual_format = _detect_image_format(img_bytes) or image_format
|
|
250
|
+
|
|
251
|
+
images.append(img_bytes)
|
|
252
|
+
|
|
253
|
+
if response_format == "url":
|
|
254
|
+
uploaded_url = upload_file_with_retry(img_bytes, actual_format)
|
|
255
|
+
if not uploaded_url:
|
|
256
|
+
uploaded_url = upload_file_alternative(img_bytes, actual_format)
|
|
257
|
+
if uploaded_url:
|
|
258
|
+
urls.append(uploaded_url)
|
|
259
|
+
else:
|
|
260
|
+
raise RuntimeError(
|
|
261
|
+
"Failed to upload image to catbox.moe using all available methods"
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
result_data = []
|
|
265
|
+
if response_format == "url":
|
|
266
|
+
for url in urls:
|
|
267
|
+
result_data.append(ImageData(url=url))
|
|
268
|
+
elif response_format == "b64_json":
|
|
269
|
+
for img in images:
|
|
270
|
+
b64 = base64.b64encode(img).decode("utf-8")
|
|
271
|
+
result_data.append(ImageData(b64_json=b64))
|
|
272
|
+
else:
|
|
273
|
+
raise ValueError("response_format must be 'url' or 'b64_json'")
|
|
274
|
+
|
|
275
|
+
from time import time as _time
|
|
276
|
+
|
|
277
|
+
return ImageResponse(created=int(_time()), data=result_data)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class PollinationsAI(TTICompatibleProvider):
|
|
281
|
+
"""PollinationsAI TTI Provider - Allows setting a custom seed for reproducible results."""
|
|
282
|
+
|
|
283
|
+
# Provider status
|
|
284
|
+
required_auth: bool = False # No authentication required
|
|
285
|
+
working: bool = True # Currently working
|
|
286
|
+
|
|
287
|
+
AVAILABLE_MODELS = [
|
|
288
|
+
"flux",
|
|
289
|
+
"flux-pro",
|
|
290
|
+
"flux-realism",
|
|
291
|
+
"flux-anime",
|
|
292
|
+
"flux-3d",
|
|
293
|
+
"any-dark",
|
|
294
|
+
"turbo",
|
|
295
|
+
"gptimage",
|
|
296
|
+
]
|
|
297
|
+
|
|
298
|
+
def __init__(self):
|
|
299
|
+
self.api_endpoint = "https://image.pollinations.ai/prompt"
|
|
300
|
+
self.session = requests.Session()
|
|
301
|
+
self.user_agent = LitAgent().random()
|
|
302
|
+
self.headers = {
|
|
303
|
+
"accept": "*/*",
|
|
304
|
+
"accept-language": "en-US,en;q=0.9",
|
|
305
|
+
"content-type": "application/json",
|
|
306
|
+
"origin": "https://image.pollinations.ai",
|
|
307
|
+
"referer": "https://image.pollinations.ai/",
|
|
308
|
+
"user-agent": self.user_agent,
|
|
309
|
+
}
|
|
310
|
+
self.session.headers.update(self.headers)
|
|
311
|
+
self.images = Images(self)
|
|
312
|
+
|
|
313
|
+
@property
|
|
314
|
+
def models(self) -> SimpleModelList:
|
|
315
|
+
return SimpleModelList(type(self).AVAILABLE_MODELS)
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
if __name__ == "__main__":
|
|
319
|
+
from rich import print
|
|
320
|
+
|
|
321
|
+
client = PollinationsAI()
|
|
322
|
+
response = client.images.create(
|
|
323
|
+
model="flux",
|
|
324
|
+
prompt="a japanese waifu in short kimono clothes",
|
|
325
|
+
response_format="url",
|
|
326
|
+
n=4,
|
|
327
|
+
timeout=30,
|
|
328
|
+
seed=None, # You can set a specific seed for reproducibility
|
|
329
|
+
convert_format=False, # Set to True to convert format (requires Pillow)
|
|
330
|
+
)
|
|
331
|
+
print(response)
|