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.
- webscout/AIauto.py +34 -16
- webscout/AIbase.py +96 -37
- webscout/AIutel.py +491 -87
- webscout/Bard.py +441 -323
- webscout/Extra/GitToolkit/__init__.py +10 -10
- webscout/Extra/YTToolkit/ytapi/video.py +232 -232
- webscout/Litlogger/README.md +10 -0
- webscout/Litlogger/__init__.py +7 -59
- webscout/Litlogger/formats.py +4 -0
- webscout/Litlogger/handlers.py +103 -0
- webscout/Litlogger/levels.py +13 -0
- webscout/Litlogger/logger.py +92 -0
- webscout/Provider/AISEARCH/Perplexity.py +332 -358
- webscout/Provider/AISEARCH/felo_search.py +9 -35
- webscout/Provider/AISEARCH/genspark_search.py +30 -56
- webscout/Provider/AISEARCH/hika_search.py +4 -16
- webscout/Provider/AISEARCH/iask_search.py +410 -436
- webscout/Provider/AISEARCH/monica_search.py +4 -30
- webscout/Provider/AISEARCH/scira_search.py +6 -32
- webscout/Provider/AISEARCH/webpilotai_search.py +38 -64
- webscout/Provider/Blackboxai.py +155 -35
- webscout/Provider/ChatSandbox.py +2 -1
- webscout/Provider/Deepinfra.py +339 -339
- webscout/Provider/ExaChat.py +358 -358
- webscout/Provider/Gemini.py +169 -169
- webscout/Provider/GithubChat.py +1 -2
- webscout/Provider/Glider.py +3 -3
- webscout/Provider/HeckAI.py +172 -82
- webscout/Provider/LambdaChat.py +1 -0
- webscout/Provider/MCPCore.py +7 -3
- webscout/Provider/OPENAI/BLACKBOXAI.py +421 -139
- webscout/Provider/OPENAI/Cloudflare.py +38 -21
- webscout/Provider/OPENAI/FalconH1.py +457 -0
- webscout/Provider/OPENAI/FreeGemini.py +35 -18
- webscout/Provider/OPENAI/NEMOTRON.py +34 -34
- webscout/Provider/OPENAI/PI.py +427 -0
- webscout/Provider/OPENAI/Qwen3.py +304 -0
- webscout/Provider/OPENAI/README.md +952 -1253
- webscout/Provider/OPENAI/TwoAI.py +374 -0
- webscout/Provider/OPENAI/__init__.py +7 -1
- webscout/Provider/OPENAI/ai4chat.py +73 -63
- webscout/Provider/OPENAI/api.py +869 -644
- webscout/Provider/OPENAI/base.py +2 -0
- webscout/Provider/OPENAI/c4ai.py +34 -13
- webscout/Provider/OPENAI/chatgpt.py +575 -556
- webscout/Provider/OPENAI/chatgptclone.py +512 -487
- webscout/Provider/OPENAI/chatsandbox.py +11 -6
- webscout/Provider/OPENAI/copilot.py +258 -0
- webscout/Provider/OPENAI/deepinfra.py +327 -318
- webscout/Provider/OPENAI/e2b.py +140 -104
- webscout/Provider/OPENAI/exaai.py +420 -411
- webscout/Provider/OPENAI/exachat.py +448 -443
- webscout/Provider/OPENAI/flowith.py +7 -3
- webscout/Provider/OPENAI/freeaichat.py +12 -8
- webscout/Provider/OPENAI/glider.py +15 -8
- webscout/Provider/OPENAI/groq.py +5 -2
- webscout/Provider/OPENAI/heckai.py +311 -307
- webscout/Provider/OPENAI/llmchatco.py +9 -7
- webscout/Provider/OPENAI/mcpcore.py +18 -9
- webscout/Provider/OPENAI/multichat.py +7 -5
- webscout/Provider/OPENAI/netwrck.py +16 -11
- webscout/Provider/OPENAI/oivscode.py +290 -0
- webscout/Provider/OPENAI/opkfc.py +507 -496
- webscout/Provider/OPENAI/pydantic_imports.py +172 -0
- webscout/Provider/OPENAI/scirachat.py +29 -17
- webscout/Provider/OPENAI/sonus.py +308 -303
- webscout/Provider/OPENAI/standardinput.py +442 -433
- webscout/Provider/OPENAI/textpollinations.py +18 -11
- webscout/Provider/OPENAI/toolbaz.py +419 -413
- webscout/Provider/OPENAI/typefully.py +17 -10
- webscout/Provider/OPENAI/typegpt.py +21 -11
- webscout/Provider/OPENAI/uncovrAI.py +477 -462
- webscout/Provider/OPENAI/utils.py +90 -79
- webscout/Provider/OPENAI/venice.py +435 -425
- webscout/Provider/OPENAI/wisecat.py +387 -381
- webscout/Provider/OPENAI/writecream.py +166 -163
- webscout/Provider/OPENAI/x0gpt.py +26 -37
- webscout/Provider/OPENAI/yep.py +384 -356
- webscout/Provider/PI.py +2 -1
- webscout/Provider/TTI/README.md +55 -101
- webscout/Provider/TTI/__init__.py +4 -9
- webscout/Provider/TTI/aiarta.py +365 -0
- webscout/Provider/TTI/artbit.py +0 -0
- webscout/Provider/TTI/base.py +64 -0
- webscout/Provider/TTI/fastflux.py +200 -0
- webscout/Provider/TTI/magicstudio.py +201 -0
- webscout/Provider/TTI/piclumen.py +203 -0
- webscout/Provider/TTI/pixelmuse.py +225 -0
- webscout/Provider/TTI/pollinations.py +221 -0
- webscout/Provider/TTI/utils.py +11 -0
- webscout/Provider/TTS/__init__.py +2 -1
- webscout/Provider/TTS/base.py +159 -159
- webscout/Provider/TTS/openai_fm.py +129 -0
- webscout/Provider/TextPollinationsAI.py +308 -308
- webscout/Provider/TwoAI.py +239 -44
- webscout/Provider/UNFINISHED/Youchat.py +330 -330
- webscout/Provider/UNFINISHED/puterjs.py +635 -0
- webscout/Provider/UNFINISHED/test_lmarena.py +119 -119
- webscout/Provider/Writecream.py +246 -246
- webscout/Provider/__init__.py +2 -2
- webscout/Provider/ai4chat.py +33 -8
- webscout/Provider/granite.py +41 -6
- webscout/Provider/koala.py +169 -169
- webscout/Provider/oivscode.py +309 -0
- webscout/Provider/samurai.py +3 -2
- webscout/Provider/scnet.py +1 -0
- webscout/Provider/typegpt.py +3 -3
- webscout/Provider/uncovr.py +368 -368
- webscout/client.py +70 -0
- webscout/litprinter/__init__.py +58 -58
- webscout/optimizers.py +419 -419
- webscout/scout/README.md +3 -1
- webscout/scout/core/crawler.py +134 -64
- webscout/scout/core/scout.py +148 -109
- webscout/scout/element.py +106 -88
- webscout/swiftcli/Readme.md +323 -323
- webscout/swiftcli/plugins/manager.py +9 -2
- webscout/version.py +1 -1
- webscout/zeroart/__init__.py +134 -134
- webscout/zeroart/effects.py +100 -100
- webscout/zeroart/fonts.py +1238 -1238
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/METADATA +160 -35
- webscout-8.3.dist-info/RECORD +290 -0
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/WHEEL +1 -1
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/entry_points.txt +1 -0
- webscout/Litlogger/Readme.md +0 -175
- 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/Provider/ChatGPTGratis.py +0 -194
- webscout/Provider/TTI/AiForce/README.md +0 -159
- 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/README.md +0 -99
- 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/README.md +0 -174
- 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/README.md +0 -101
- 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/README.md +0 -155
- 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/README.md +0 -146
- 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/README.md +0 -134
- 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/README.md +0 -100
- 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/README.md +0 -129
- 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/README.md +0 -114
- 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/README.md +0 -161
- 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/README.md +0 -79
- 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/README.md +0 -139
- 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/UNFINISHED/oivscode.py +0 -351
- webscout-8.2.8.dist-info/RECORD +0 -334
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/top_level.txt +0 -0
|
@@ -1,440 +0,0 @@
|
|
|
1
|
-
"""AIArtaImager Synchronous Provider - Generate stunning AI art with AI Arta! 🎨
|
|
2
|
-
|
|
3
|
-
Examples:
|
|
4
|
-
>>> from webscout import AIArtaImager
|
|
5
|
-
>>> provider = AIArtaImager()
|
|
6
|
-
>>>
|
|
7
|
-
>>> # Generate a single image
|
|
8
|
-
>>> images = provider.generate("A cool cyberpunk city at night")
|
|
9
|
-
>>> paths = provider.save(images, dir="my_images")
|
|
10
|
-
>>>
|
|
11
|
-
>>> # Generate multiple images with different settings
|
|
12
|
-
>>> images = provider.generate(
|
|
13
|
-
... prompt="Epic dragon breathing fire",
|
|
14
|
-
... amount=2,
|
|
15
|
-
... model="flux"
|
|
16
|
-
... )
|
|
17
|
-
>>> provider.save(images, dir="dragon_pics")
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
import requests
|
|
21
|
-
import json
|
|
22
|
-
import os
|
|
23
|
-
import time
|
|
24
|
-
from pathlib import Path
|
|
25
|
-
from typing import List, Optional, Union, Dict, Any
|
|
26
|
-
from requests.exceptions import RequestException
|
|
27
|
-
|
|
28
|
-
from webscout.AIbase import ImageProvider
|
|
29
|
-
from webscout.litagent import LitAgent
|
|
30
|
-
|
|
31
|
-
agent = LitAgent()
|
|
32
|
-
|
|
33
|
-
class AIArtaImager(ImageProvider):
|
|
34
|
-
"""Your go-to provider for generating fire images with AI Arta! 🎨
|
|
35
|
-
|
|
36
|
-
Examples:
|
|
37
|
-
>>> provider = AIArtaImager()
|
|
38
|
-
>>> # Generate one image
|
|
39
|
-
>>> image = provider.generate("A futuristic city")
|
|
40
|
-
>>> provider.save(image, "city.png")
|
|
41
|
-
>>>
|
|
42
|
-
>>> # Generate multiple images with specific model
|
|
43
|
-
>>> images = provider.generate(
|
|
44
|
-
... prompt="Space station",
|
|
45
|
-
... amount=3,
|
|
46
|
-
... model="flux_black_ink"
|
|
47
|
-
... )
|
|
48
|
-
>>> provider.save(images, dir="space_pics")
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
# API endpoints
|
|
52
|
-
url = "https://img-gen-prod.ai-arta.com"
|
|
53
|
-
auth_url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=AIzaSyB3-71wG0fIt0shj0ee4fvx1shcjJHGrrQ"
|
|
54
|
-
token_refresh_url = "https://securetoken.googleapis.com/v1/token?key=AIzaSyB3-71wG0fIt0shj0ee4fvx1shcjJHGrrQ"
|
|
55
|
-
image_generation_url = "https://img-gen-prod.ai-arta.com/api/v1/text2image"
|
|
56
|
-
status_check_url = "https://img-gen-prod.ai-arta.com/api/v1/text2image/{record_id}/status"
|
|
57
|
-
|
|
58
|
-
# Available models
|
|
59
|
-
AVAILABLE_MODELS = {
|
|
60
|
-
"flux": "Flux",
|
|
61
|
-
"medieval": "Medieval",
|
|
62
|
-
"vincent_van_gogh": "Vincent Van Gogh",
|
|
63
|
-
"f_dev": "F Dev",
|
|
64
|
-
"low_poly": "Low Poly",
|
|
65
|
-
"dreamshaper_xl": "Dreamshaper-xl",
|
|
66
|
-
"anima_pencil_xl": "Anima-pencil-xl",
|
|
67
|
-
"biomech": "Biomech",
|
|
68
|
-
"trash_polka": "Trash Polka",
|
|
69
|
-
"no_style": "No Style",
|
|
70
|
-
"cheyenne_xl": "Cheyenne-xl",
|
|
71
|
-
"chicano": "Chicano",
|
|
72
|
-
"embroidery_tattoo": "Embroidery tattoo",
|
|
73
|
-
"red_and_black": "Red and Black",
|
|
74
|
-
"fantasy_art": "Fantasy Art",
|
|
75
|
-
"watercolor": "Watercolor",
|
|
76
|
-
"dotwork": "Dotwork",
|
|
77
|
-
"old_school_colored": "Old school colored",
|
|
78
|
-
"realistic_tattoo": "Realistic tattoo",
|
|
79
|
-
"japanese_2": "Japanese_2",
|
|
80
|
-
"realistic_stock_xl": "Realistic-stock-xl",
|
|
81
|
-
"f_pro": "F Pro",
|
|
82
|
-
"revanimated": "RevAnimated",
|
|
83
|
-
"katayama_mix_xl": "Katayama-mix-xl",
|
|
84
|
-
"sdxl_l": "SDXL L",
|
|
85
|
-
"cor_epica_xl": "Cor-epica-xl",
|
|
86
|
-
"anime_tattoo": "Anime tattoo",
|
|
87
|
-
"new_school": "New School",
|
|
88
|
-
"death_metal": "Death metal",
|
|
89
|
-
"old_school": "Old School",
|
|
90
|
-
"juggernaut_xl": "Juggernaut-xl",
|
|
91
|
-
"photographic": "Photographic",
|
|
92
|
-
"sdxl_1_0": "SDXL 1.0",
|
|
93
|
-
"graffiti": "Graffiti",
|
|
94
|
-
"mini_tattoo": "Mini tattoo",
|
|
95
|
-
"surrealism": "Surrealism",
|
|
96
|
-
"neo_traditional": "Neo-traditional",
|
|
97
|
-
"on_limbs_black": "On limbs black",
|
|
98
|
-
# "yamers_realistic_xl": "Yamers-realistic-xl",
|
|
99
|
-
# "pony_xl": "Pony-xl",
|
|
100
|
-
# "playground_xl": "Playground-xl",
|
|
101
|
-
# "anything_xl": "Anything-xl",
|
|
102
|
-
# "flame_design": "Flame design",
|
|
103
|
-
# "kawaii": "Kawaii",
|
|
104
|
-
# "cinematic_art": "Cinematic Art",
|
|
105
|
-
# "professional": "Professional",
|
|
106
|
-
# "flux_black_ink": "Flux Black Ink"
|
|
107
|
-
}
|
|
108
|
-
models = list(AVAILABLE_MODELS.keys())
|
|
109
|
-
|
|
110
|
-
def __init__(self, timeout: int = 60, proxies: dict = None, logging: bool = True):
|
|
111
|
-
"""Initialize your AIArtaImager provider with custom settings
|
|
112
|
-
|
|
113
|
-
Examples:
|
|
114
|
-
>>> provider = AIArtaImager(timeout=120)
|
|
115
|
-
>>> provider = AIArtaImager(proxies={"http": "http://proxy:8080"})
|
|
116
|
-
|
|
117
|
-
Args:
|
|
118
|
-
timeout (int): HTTP request timeout in seconds (default: 60)
|
|
119
|
-
proxies (dict, optional): Proxy configuration for requests
|
|
120
|
-
logging (bool): Enable/disable logging (default: True)
|
|
121
|
-
"""
|
|
122
|
-
self.headers = {
|
|
123
|
-
"Accept": "application/json",
|
|
124
|
-
"Accept-Language": "en-US,en;q=0.5",
|
|
125
|
-
"User-Agent": agent.random()
|
|
126
|
-
}
|
|
127
|
-
self.session = requests.Session()
|
|
128
|
-
self.session.headers.update(self.headers)
|
|
129
|
-
if proxies:
|
|
130
|
-
self.session.proxies.update(proxies)
|
|
131
|
-
self.timeout = timeout
|
|
132
|
-
self.prompt: str = "AI-generated image - webscout"
|
|
133
|
-
self.image_extension: str = "png"
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def get_auth_file(self) -> Path:
|
|
137
|
-
"""Get path to authentication file"""
|
|
138
|
-
path = Path(os.path.join(os.path.expanduser("~"), ".ai_arta_cookies"))
|
|
139
|
-
path.mkdir(exist_ok=True)
|
|
140
|
-
filename = f"auth_{self.__class__.__name__}.json"
|
|
141
|
-
return path / filename
|
|
142
|
-
|
|
143
|
-
def create_token(self, path: Path) -> Dict[str, Any]:
|
|
144
|
-
"""Create a new authentication token"""
|
|
145
|
-
# Step 1: Generate Authentication Token
|
|
146
|
-
auth_payload = {"clientType": "CLIENT_TYPE_ANDROID"}
|
|
147
|
-
proxies = self.session.proxies if self.session.proxies else None
|
|
148
|
-
|
|
149
|
-
auth_response = self.session.post(self.auth_url, json=auth_payload, timeout=self.timeout, proxies=proxies)
|
|
150
|
-
auth_data = auth_response.json()
|
|
151
|
-
auth_token = auth_data.get("idToken")
|
|
152
|
-
|
|
153
|
-
if not auth_token:
|
|
154
|
-
|
|
155
|
-
raise Exception("Failed to obtain authentication token.")
|
|
156
|
-
|
|
157
|
-
with open(path, 'w') as f:
|
|
158
|
-
json.dump(auth_data, f)
|
|
159
|
-
|
|
160
|
-
return auth_data
|
|
161
|
-
|
|
162
|
-
def refresh_token(self, refresh_token: str) -> tuple[str, str]:
|
|
163
|
-
"""Refresh authentication token"""
|
|
164
|
-
payload = {
|
|
165
|
-
"grant_type": "refresh_token",
|
|
166
|
-
"refresh_token": refresh_token,
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
response = self.session.post(self.token_refresh_url, data=payload, timeout=self.timeout)
|
|
170
|
-
response_data = response.json()
|
|
171
|
-
|
|
172
|
-
return response_data.get("id_token"), response_data.get("refresh_token")
|
|
173
|
-
|
|
174
|
-
def read_and_refresh_token(self) -> Dict[str, Any]:
|
|
175
|
-
"""Read token from file and refresh if needed"""
|
|
176
|
-
path = self.get_auth_file()
|
|
177
|
-
|
|
178
|
-
if path.is_file():
|
|
179
|
-
with open(path, 'r') as f:
|
|
180
|
-
auth_data = json.load(f)
|
|
181
|
-
|
|
182
|
-
diff = time.time() - os.path.getmtime(path)
|
|
183
|
-
expires_in = int(auth_data.get("expiresIn"))
|
|
184
|
-
|
|
185
|
-
if diff < expires_in:
|
|
186
|
-
if diff > expires_in / 2:
|
|
187
|
-
auth_data["idToken"], auth_data["refreshToken"] = self.refresh_token(
|
|
188
|
-
auth_data.get("refreshToken")
|
|
189
|
-
)
|
|
190
|
-
with open(path, 'w') as f:
|
|
191
|
-
json.dump(auth_data, f)
|
|
192
|
-
return auth_data
|
|
193
|
-
|
|
194
|
-
# Create new token if file doesn't exist or token expired
|
|
195
|
-
return self.create_token(path)
|
|
196
|
-
|
|
197
|
-
def get_model(self, model_name: str) -> str:
|
|
198
|
-
"""Get actual model name from alias"""
|
|
199
|
-
if model_name.lower() in self.AVAILABLE_MODELS:
|
|
200
|
-
return self.AVAILABLE_MODELS[model_name.lower()]
|
|
201
|
-
return model_name
|
|
202
|
-
|
|
203
|
-
def generate(
|
|
204
|
-
self,
|
|
205
|
-
prompt: str,
|
|
206
|
-
amount: int = 1,
|
|
207
|
-
model: str = "Flux",
|
|
208
|
-
negative_prompt: str = "blurry, deformed hands, ugly",
|
|
209
|
-
guidance_scale: int = 7,
|
|
210
|
-
num_inference_steps: int = 30,
|
|
211
|
-
aspect_ratio: str = "1:1",
|
|
212
|
-
max_retries: int = 3,
|
|
213
|
-
retry_delay: int = 5,
|
|
214
|
-
**kwargs
|
|
215
|
-
) -> List[bytes]:
|
|
216
|
-
"""Generate some fire images from your prompt! 🎨
|
|
217
|
-
|
|
218
|
-
Examples:
|
|
219
|
-
>>> provider = AIArtaImager()
|
|
220
|
-
>>> # Basic usage
|
|
221
|
-
>>> images = provider.generate("Cool art")
|
|
222
|
-
>>> # Advanced usage
|
|
223
|
-
>>> images = provider.generate(
|
|
224
|
-
... prompt="Epic dragon",
|
|
225
|
-
... amount=2,
|
|
226
|
-
... model="fantasy_art",
|
|
227
|
-
... negative_prompt="ugly, deformed"
|
|
228
|
-
... )
|
|
229
|
-
|
|
230
|
-
Args:
|
|
231
|
-
prompt (str): Your image description
|
|
232
|
-
amount (int): How many images you want (default: 1)
|
|
233
|
-
model (str): Model to use - check AVAILABLE_MODELS (default: "flux")
|
|
234
|
-
negative_prompt (str): What you don't want in the image
|
|
235
|
-
guidance_scale (int): Controls how closely the model follows your prompt
|
|
236
|
-
num_inference_steps (int): More steps = better quality but slower
|
|
237
|
-
aspect_ratio (str): Image aspect ratio (default: "1:1")
|
|
238
|
-
max_retries (int): Max retry attempts if something fails
|
|
239
|
-
retry_delay (int): Seconds to wait between retries
|
|
240
|
-
**kwargs: Additional parameters for future compatibility
|
|
241
|
-
|
|
242
|
-
Returns:
|
|
243
|
-
List[bytes]: Your generated images
|
|
244
|
-
|
|
245
|
-
Raises:
|
|
246
|
-
ValueError: If the inputs ain't valid
|
|
247
|
-
RequestException: If the API calls fail after retries
|
|
248
|
-
"""
|
|
249
|
-
if not prompt:
|
|
250
|
-
raise ValueError("Yo fam, the prompt can't be empty! 🤔")
|
|
251
|
-
if not isinstance(amount, int) or amount < 1:
|
|
252
|
-
raise ValueError("Amount needs to be a positive number! 📈")
|
|
253
|
-
|
|
254
|
-
model_name = self.get_model(model)
|
|
255
|
-
self.prompt = prompt
|
|
256
|
-
response = []
|
|
257
|
-
|
|
258
|
-
# Step 1: Get Authentication Token
|
|
259
|
-
auth_data = self.read_and_refresh_token()
|
|
260
|
-
|
|
261
|
-
# Headers for generation requests
|
|
262
|
-
gen_headers = {
|
|
263
|
-
"Authorization": auth_data.get("idToken"),
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
for i in range(amount):
|
|
267
|
-
# Step 2: Generate Image
|
|
268
|
-
image_payload = {
|
|
269
|
-
"prompt": prompt,
|
|
270
|
-
"negative_prompt": negative_prompt,
|
|
271
|
-
"style": model_name,
|
|
272
|
-
"images_num": "1", # Generate 1 at a time
|
|
273
|
-
"cfg_scale": str(guidance_scale),
|
|
274
|
-
"steps": str(num_inference_steps),
|
|
275
|
-
"aspect_ratio": aspect_ratio,
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
for attempt in range(max_retries):
|
|
279
|
-
try:
|
|
280
|
-
|
|
281
|
-
# Submit generation request
|
|
282
|
-
image_response = self.session.post(
|
|
283
|
-
self.image_generation_url,
|
|
284
|
-
data=image_payload,
|
|
285
|
-
headers=gen_headers,
|
|
286
|
-
timeout=self.timeout
|
|
287
|
-
)
|
|
288
|
-
image_response.raise_for_status()
|
|
289
|
-
image_data = image_response.json()
|
|
290
|
-
record_id = image_data.get("record_id")
|
|
291
|
-
|
|
292
|
-
if not record_id:
|
|
293
|
-
raise RequestException(f"Failed to initiate image generation: {image_data}")
|
|
294
|
-
|
|
295
|
-
# Step 3: Check Generation Status
|
|
296
|
-
status_url = self.status_check_url.format(record_id=record_id)
|
|
297
|
-
|
|
298
|
-
counter = 0
|
|
299
|
-
dots = [".", "..", "...", "...."]
|
|
300
|
-
|
|
301
|
-
while True:
|
|
302
|
-
status_response = self.session.get(
|
|
303
|
-
status_url,
|
|
304
|
-
headers=gen_headers,
|
|
305
|
-
timeout=self.timeout
|
|
306
|
-
)
|
|
307
|
-
status_data = status_response.json()
|
|
308
|
-
status = status_data.get("status")
|
|
309
|
-
|
|
310
|
-
if status == "DONE":
|
|
311
|
-
image_urls = [image["url"] for image in status_data.get("response", [])]
|
|
312
|
-
|
|
313
|
-
if not image_urls:
|
|
314
|
-
raise RequestException("No image URLs in response")
|
|
315
|
-
|
|
316
|
-
# Download the generated image
|
|
317
|
-
image_response = self.session.get(image_urls[0], timeout=self.timeout)
|
|
318
|
-
image_response.raise_for_status()
|
|
319
|
-
response.append(image_response.content)
|
|
320
|
-
break
|
|
321
|
-
|
|
322
|
-
elif status in ("IN_QUEUE", "IN_PROGRESS"):
|
|
323
|
-
# status_text = "Waiting" if status == "IN_QUEUE" else "Generating"
|
|
324
|
-
time.sleep(3)
|
|
325
|
-
counter += 1
|
|
326
|
-
|
|
327
|
-
else:
|
|
328
|
-
raise RequestException(f"Image generation failed with status: {status}")
|
|
329
|
-
|
|
330
|
-
# If we got here, we successfully generated an image
|
|
331
|
-
break
|
|
332
|
-
|
|
333
|
-
except RequestException as e:
|
|
334
|
-
if attempt == max_retries - 1:
|
|
335
|
-
raise
|
|
336
|
-
else:
|
|
337
|
-
time.sleep(retry_delay)
|
|
338
|
-
|
|
339
|
-
return response
|
|
340
|
-
|
|
341
|
-
def save(
|
|
342
|
-
self,
|
|
343
|
-
response: List[bytes],
|
|
344
|
-
name: Optional[str] = None,
|
|
345
|
-
dir: Optional[Union[str, Path]] = None,
|
|
346
|
-
filenames_prefix: str = "",
|
|
347
|
-
) -> List[str]:
|
|
348
|
-
"""Save your fire generated images! 💾
|
|
349
|
-
|
|
350
|
-
Examples:
|
|
351
|
-
>>> provider = AIArtaImager()
|
|
352
|
-
>>> images = provider.generate("Cool art")
|
|
353
|
-
>>> # Save with default settings
|
|
354
|
-
>>> paths = provider.save(images)
|
|
355
|
-
>>> # Save with custom name and directory
|
|
356
|
-
>>> paths = provider.save(
|
|
357
|
-
... images,
|
|
358
|
-
... name="my_art",
|
|
359
|
-
... dir="my_images",
|
|
360
|
-
... filenames_prefix="test_"
|
|
361
|
-
... )
|
|
362
|
-
|
|
363
|
-
Args:
|
|
364
|
-
response (List[bytes]): Your generated images
|
|
365
|
-
name (Optional[str]): Custom name for your images
|
|
366
|
-
dir (Optional[Union[str, Path]]): Where to save the images (default: current directory)
|
|
367
|
-
filenames_prefix (str): Prefix for your image files
|
|
368
|
-
|
|
369
|
-
Returns:
|
|
370
|
-
List[str]: Paths to your saved images
|
|
371
|
-
"""
|
|
372
|
-
save_dir = dir if dir else os.getcwd()
|
|
373
|
-
if not os.path.exists(save_dir):
|
|
374
|
-
os.makedirs(save_dir)
|
|
375
|
-
|
|
376
|
-
name = self.prompt if name is None else name
|
|
377
|
-
|
|
378
|
-
# Clean up name for filename use
|
|
379
|
-
safe_name = "".join(c if c.isalnum() or c in "_-" else "_" for c in name)
|
|
380
|
-
safe_name = safe_name[:50] # Truncate if too long
|
|
381
|
-
|
|
382
|
-
filenames = []
|
|
383
|
-
count = 0
|
|
384
|
-
|
|
385
|
-
for image in response:
|
|
386
|
-
def complete_path():
|
|
387
|
-
count_value = "" if count == 0 else f"_{count}"
|
|
388
|
-
return os.path.join(save_dir, filenames_prefix + safe_name + count_value + "." + self.image_extension)
|
|
389
|
-
|
|
390
|
-
while os.path.isfile(complete_path()):
|
|
391
|
-
count += 1
|
|
392
|
-
|
|
393
|
-
filepath = complete_path()
|
|
394
|
-
filenames.append(os.path.basename(filepath))
|
|
395
|
-
|
|
396
|
-
with open(filepath, "wb") as fh:
|
|
397
|
-
fh.write(image)
|
|
398
|
-
return filenames
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if __name__ == "__main__":
|
|
402
|
-
# Example usage
|
|
403
|
-
bot = AIArtaImager()
|
|
404
|
-
test_prompt = "A shiny red sports car speeding down a scenic mountain road"
|
|
405
|
-
|
|
406
|
-
print(f"Testing all available models with prompt: '{test_prompt}'")
|
|
407
|
-
print("-" * 50)
|
|
408
|
-
|
|
409
|
-
# Create a directory for test images if it doesn't exist
|
|
410
|
-
test_dir = "model_test_images"
|
|
411
|
-
if not os.path.exists(test_dir):
|
|
412
|
-
os.makedirs(test_dir)
|
|
413
|
-
|
|
414
|
-
for model in bot.AVAILABLE_MODELS:
|
|
415
|
-
print(f"Testing model: {model}")
|
|
416
|
-
try:
|
|
417
|
-
# Generate an image with the current model
|
|
418
|
-
resp = bot.generate(
|
|
419
|
-
prompt=test_prompt,
|
|
420
|
-
amount=1,
|
|
421
|
-
model=model,
|
|
422
|
-
width=768,
|
|
423
|
-
height=768
|
|
424
|
-
)
|
|
425
|
-
|
|
426
|
-
# Save the image with model name as prefix
|
|
427
|
-
saved_paths = bot.save(
|
|
428
|
-
resp,
|
|
429
|
-
name=f"{model}_test",
|
|
430
|
-
dir=test_dir,
|
|
431
|
-
filenames_prefix=f"{model}_"
|
|
432
|
-
)
|
|
433
|
-
|
|
434
|
-
print(f"✓ Success! Saved image: {saved_paths[0]}")
|
|
435
|
-
except Exception as e:
|
|
436
|
-
print(f"✗ Failed with model {model}: {str(e)}")
|
|
437
|
-
|
|
438
|
-
print("-" * 30)
|
|
439
|
-
|
|
440
|
-
print("All model tests completed!")
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# 🔥 Artbit Image Providers
|
|
2
|
-
|
|
3
|
-
Your go-to solution for generating fire images with Artbit.ai! Both sync and async support! 🚀
|
|
4
|
-
|
|
5
|
-
## 🌟 Features
|
|
6
|
-
|
|
7
|
-
- 🎨 Support for all Artbit models
|
|
8
|
-
- ⚡ Both sync and async implementations
|
|
9
|
-
- 🔄 Smart retry mechanism
|
|
10
|
-
- 🌐 Proxy support
|
|
11
|
-
- 📝 Optional logging
|
|
12
|
-
- 🎯 Type hints
|
|
13
|
-
- 🚀 Easy to use
|
|
14
|
-
|
|
15
|
-
## 📦 Installation
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
pip install webscout
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## 🚀 Quick Start
|
|
22
|
-
|
|
23
|
-
### Sync Usage
|
|
24
|
-
|
|
25
|
-
```python
|
|
26
|
-
from webscout import ArtbitImager
|
|
27
|
-
|
|
28
|
-
# Initialize with logging
|
|
29
|
-
provider = ArtbitImager(logging=True)
|
|
30
|
-
|
|
31
|
-
# Generate a single image
|
|
32
|
-
images = provider.generate("A shiny red sports car")
|
|
33
|
-
paths = provider.save(images)
|
|
34
|
-
|
|
35
|
-
# Generate multiple images with parameters
|
|
36
|
-
images = provider.generate(
|
|
37
|
-
prompt="Epic dragon in cyberpunk city",
|
|
38
|
-
amount=3,
|
|
39
|
-
caption_model="sdxl",
|
|
40
|
-
selected_ratio="1024",
|
|
41
|
-
negative_prompt="blurry, bad quality"
|
|
42
|
-
)
|
|
43
|
-
paths = provider.save(images, name="dragon", dir="outputs")
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Async Usage
|
|
47
|
-
|
|
48
|
-
```python
|
|
49
|
-
from webscout import AsyncArtbitImager
|
|
50
|
-
import asyncio
|
|
51
|
-
|
|
52
|
-
async def example():
|
|
53
|
-
# Initialize with logging
|
|
54
|
-
provider = AsyncArtbitImager(logging=True)
|
|
55
|
-
|
|
56
|
-
# Generate a single image
|
|
57
|
-
images = await provider.generate("A shiny red sports car")
|
|
58
|
-
paths = await provider.save(images)
|
|
59
|
-
|
|
60
|
-
# Generate multiple images with parameters
|
|
61
|
-
images = await provider.generate(
|
|
62
|
-
prompt="Epic dragon in cyberpunk city",
|
|
63
|
-
amount=3,
|
|
64
|
-
caption_model="sdxl",
|
|
65
|
-
selected_ratio="1024",
|
|
66
|
-
negative_prompt="blurry, bad quality"
|
|
67
|
-
)
|
|
68
|
-
paths = await provider.save(images, name="dragon", dir="outputs")
|
|
69
|
-
|
|
70
|
-
# Run the example
|
|
71
|
-
asyncio.run(example())
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## 🎨 Supported Models
|
|
75
|
-
|
|
76
|
-
- `sdxl` (default) - Stable Diffusion XL
|
|
77
|
-
- `sd` - Stable Diffusion
|
|
78
|
-
- And more coming soon! 🎉
|
|
79
|
-
|
|
80
|
-
## ⚙️ Configuration Options
|
|
81
|
-
|
|
82
|
-
- `timeout`: Request timeout in seconds
|
|
83
|
-
- `proxies`: Proxy settings for requests
|
|
84
|
-
- `logging`: Enable/disable fire logging
|
|
85
|
-
|
|
86
|
-
## 🎯 Generation Parameters
|
|
87
|
-
|
|
88
|
-
- `prompt`: Your image description
|
|
89
|
-
- `amount`: Number of images to generate
|
|
90
|
-
- `caption_model`: Which model to use
|
|
91
|
-
- `selected_ratio`: Image size ratio
|
|
92
|
-
- `negative_prompt`: What you don't want in the image
|
|
93
|
-
|
|
94
|
-
## 💾 Save Options
|
|
95
|
-
|
|
96
|
-
- `name`: Custom name for your images
|
|
97
|
-
- `dir`: Where to save your images
|
|
98
|
-
- `filenames_prefix`: Add prefix to filenames
|
|
99
|
-
|
|
100
|
-
## 🔥 Made with Love by HelpingAI
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Artbit Providers - Your go-to solution for generating fire images! 🔥
|
|
3
|
-
|
|
4
|
-
Examples:
|
|
5
|
-
>>> # Sync Usage
|
|
6
|
-
>>> from webscout import ArtbitImager
|
|
7
|
-
>>> provider = ArtbitImager(logging=True)
|
|
8
|
-
>>> images = provider.generate("Cool art")
|
|
9
|
-
>>> paths = provider.save(images)
|
|
10
|
-
>>>
|
|
11
|
-
>>> # Async Usage
|
|
12
|
-
>>> from webscout import AsyncArtbitImager
|
|
13
|
-
>>> async def example():
|
|
14
|
-
... provider = AsyncArtbitImager(logging=True)
|
|
15
|
-
... images = await provider.generate("Epic dragon")
|
|
16
|
-
... paths = await provider.save(images)
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
from .sync_artbit import ArtbitImager
|
|
20
|
-
from .async_artbit import AsyncArtbitImager
|
|
21
|
-
|
|
22
|
-
__all__ = ["ArtbitImager", "AsyncArtbitImager"]
|