webscout 8.2.9__py3-none-any.whl → 8.3.1__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 (100) hide show
  1. webscout/AIauto.py +6 -6
  2. webscout/AIbase.py +61 -1
  3. webscout/Extra/YTToolkit/ytapi/patterns.py +45 -45
  4. webscout/Extra/YTToolkit/ytapi/stream.py +1 -1
  5. webscout/Extra/YTToolkit/ytapi/video.py +10 -10
  6. webscout/Extra/autocoder/autocoder_utiles.py +1 -1
  7. webscout/Litlogger/formats.py +9 -0
  8. webscout/Litlogger/handlers.py +18 -0
  9. webscout/Litlogger/logger.py +43 -1
  10. webscout/Provider/AISEARCH/scira_search.py +3 -2
  11. webscout/Provider/Blackboxai.py +2 -0
  12. webscout/Provider/ChatSandbox.py +2 -1
  13. webscout/Provider/Deepinfra.py +1 -1
  14. webscout/Provider/HeckAI.py +1 -1
  15. webscout/Provider/LambdaChat.py +8 -1
  16. webscout/Provider/MCPCore.py +7 -3
  17. webscout/Provider/OPENAI/BLACKBOXAI.py +396 -113
  18. webscout/Provider/OPENAI/Cloudflare.py +31 -14
  19. webscout/Provider/OPENAI/FalconH1.py +457 -0
  20. webscout/Provider/OPENAI/FreeGemini.py +29 -13
  21. webscout/Provider/OPENAI/NEMOTRON.py +26 -14
  22. webscout/Provider/OPENAI/PI.py +427 -0
  23. webscout/Provider/OPENAI/Qwen3.py +161 -140
  24. webscout/Provider/OPENAI/README.md +3 -0
  25. webscout/Provider/OPENAI/TogetherAI.py +355 -0
  26. webscout/Provider/OPENAI/TwoAI.py +29 -12
  27. webscout/Provider/OPENAI/__init__.py +4 -1
  28. webscout/Provider/OPENAI/ai4chat.py +33 -23
  29. webscout/Provider/OPENAI/api.py +375 -24
  30. webscout/Provider/OPENAI/autoproxy.py +39 -0
  31. webscout/Provider/OPENAI/base.py +91 -12
  32. webscout/Provider/OPENAI/c4ai.py +31 -10
  33. webscout/Provider/OPENAI/chatgpt.py +56 -24
  34. webscout/Provider/OPENAI/chatgptclone.py +46 -16
  35. webscout/Provider/OPENAI/chatsandbox.py +7 -3
  36. webscout/Provider/OPENAI/copilot.py +26 -10
  37. webscout/Provider/OPENAI/deepinfra.py +29 -12
  38. webscout/Provider/OPENAI/e2b.py +358 -158
  39. webscout/Provider/OPENAI/exaai.py +13 -10
  40. webscout/Provider/OPENAI/exachat.py +10 -6
  41. webscout/Provider/OPENAI/flowith.py +7 -3
  42. webscout/Provider/OPENAI/freeaichat.py +10 -6
  43. webscout/Provider/OPENAI/glider.py +10 -6
  44. webscout/Provider/OPENAI/heckai.py +11 -8
  45. webscout/Provider/OPENAI/llmchatco.py +9 -7
  46. webscout/Provider/OPENAI/mcpcore.py +10 -7
  47. webscout/Provider/OPENAI/multichat.py +3 -1
  48. webscout/Provider/OPENAI/netwrck.py +10 -6
  49. webscout/Provider/OPENAI/oivscode.py +12 -9
  50. webscout/Provider/OPENAI/opkfc.py +31 -8
  51. webscout/Provider/OPENAI/scirachat.py +17 -10
  52. webscout/Provider/OPENAI/sonus.py +10 -6
  53. webscout/Provider/OPENAI/standardinput.py +18 -9
  54. webscout/Provider/OPENAI/textpollinations.py +14 -7
  55. webscout/Provider/OPENAI/toolbaz.py +16 -11
  56. webscout/Provider/OPENAI/typefully.py +14 -7
  57. webscout/Provider/OPENAI/typegpt.py +10 -6
  58. webscout/Provider/OPENAI/uncovrAI.py +22 -8
  59. webscout/Provider/OPENAI/venice.py +10 -6
  60. webscout/Provider/OPENAI/writecream.py +13 -10
  61. webscout/Provider/OPENAI/x0gpt.py +11 -9
  62. webscout/Provider/OPENAI/yep.py +12 -10
  63. webscout/Provider/PI.py +2 -1
  64. webscout/Provider/STT/__init__.py +3 -0
  65. webscout/Provider/STT/base.py +281 -0
  66. webscout/Provider/STT/elevenlabs.py +265 -0
  67. webscout/Provider/TTI/__init__.py +3 -1
  68. webscout/Provider/TTI/aiarta.py +399 -365
  69. webscout/Provider/TTI/base.py +74 -2
  70. webscout/Provider/TTI/fastflux.py +63 -30
  71. webscout/Provider/TTI/gpt1image.py +149 -0
  72. webscout/Provider/TTI/imagen.py +196 -0
  73. webscout/Provider/TTI/magicstudio.py +60 -29
  74. webscout/Provider/TTI/piclumen.py +43 -32
  75. webscout/Provider/TTI/pixelmuse.py +232 -225
  76. webscout/Provider/TTI/pollinations.py +43 -32
  77. webscout/Provider/TTI/together.py +287 -0
  78. webscout/Provider/TTI/utils.py +2 -1
  79. webscout/Provider/TTS/README.md +1 -0
  80. webscout/Provider/TTS/__init__.py +2 -1
  81. webscout/Provider/TTS/freetts.py +140 -0
  82. webscout/Provider/UNFINISHED/ChutesAI.py +314 -0
  83. webscout/Provider/UNFINISHED/fetch_together_models.py +95 -0
  84. webscout/Provider/__init__.py +3 -2
  85. webscout/Provider/granite.py +41 -6
  86. webscout/Provider/oivscode.py +37 -37
  87. webscout/Provider/scira_chat.py +3 -2
  88. webscout/Provider/scnet.py +1 -0
  89. webscout/Provider/toolbaz.py +0 -1
  90. webscout/litagent/Readme.md +12 -3
  91. webscout/litagent/agent.py +99 -62
  92. webscout/version.py +1 -1
  93. {webscout-8.2.9.dist-info → webscout-8.3.1.dist-info}/METADATA +2 -1
  94. {webscout-8.2.9.dist-info → webscout-8.3.1.dist-info}/RECORD +98 -87
  95. {webscout-8.2.9.dist-info → webscout-8.3.1.dist-info}/WHEEL +1 -1
  96. webscout/Provider/ChatGPTGratis.py +0 -194
  97. webscout/Provider/TTI/artbit.py +0 -0
  98. {webscout-8.2.9.dist-info → webscout-8.3.1.dist-info}/entry_points.txt +0 -0
  99. {webscout-8.2.9.dist-info → webscout-8.3.1.dist-info}/licenses/LICENSE.md +0 -0
  100. {webscout-8.2.9.dist-info → webscout-8.3.1.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,10 @@ import uuid
4
4
  import time
5
5
  import tempfile
6
6
  from typing import Optional, List
7
- from webscout.Provider.TTI.utils import ImageData, ImageResponse
7
+ from webscout.Provider.TTI.utils import (
8
+ ImageData,
9
+ ImageResponse
10
+ )
8
11
  from webscout.Provider.TTI.base import TTICompatibleProvider, BaseImages
9
12
  from io import BytesIO
10
13
  from webscout.litagent import LitAgent
@@ -14,11 +17,13 @@ try:
14
17
  except ImportError:
15
18
  Image = None
16
19
 
20
+
17
21
  class Images(BaseImages):
18
22
  def __init__(self, client):
19
23
  self._client = client
20
24
 
21
- def create(self,
25
+ def create(
26
+ self,
22
27
  model: str = "magicstudio",
23
28
  prompt: str = None,
24
29
  n: int = 1,
@@ -29,7 +34,7 @@ class Images(BaseImages):
29
34
  aspect_ratio: str = None,
30
35
  timeout: int = 60,
31
36
  image_format: str = "jpg",
32
- **kwargs
37
+ **kwargs,
33
38
  ) -> ImageResponse:
34
39
  if not prompt:
35
40
  raise ValueError("Prompt is required!")
@@ -43,7 +48,7 @@ class Images(BaseImages):
43
48
  "Origin": "https://magicstudio.com",
44
49
  "Referer": "https://magicstudio.com/ai-art-generator/",
45
50
  "DNT": "1",
46
- "Sec-GPC": "1"
51
+ "Sec-GPC": "1",
47
52
  }
48
53
  session = requests.Session()
49
54
  session.headers.update(headers)
@@ -57,7 +62,11 @@ class Images(BaseImages):
57
62
  "user_is_subscribed": "false",
58
63
  "client_id": uuid.uuid4().hex,
59
64
  }
60
- resp = session.post(api_url, data=form_data, timeout=timeout)
65
+ resp = session.post(
66
+ api_url,
67
+ data=form_data,
68
+ timeout=timeout,
69
+ )
61
70
  resp.raise_for_status()
62
71
  img_bytes = resp.content
63
72
  # Convert to png or jpeg in memory if needed
@@ -65,7 +74,10 @@ class Images(BaseImages):
65
74
  with BytesIO(img_bytes) as input_io:
66
75
  with Image.open(input_io) as im:
67
76
  out_io = BytesIO()
68
- if image_format.lower() == "jpeg" or image_format.lower() == "jpg":
77
+ if (
78
+ image_format.lower() == "jpeg"
79
+ or image_format.lower() == "jpg"
80
+ ):
69
81
  im = im.convert("RGB")
70
82
  im.save(out_io, format="JPEG")
71
83
  else:
@@ -73,37 +85,43 @@ class Images(BaseImages):
73
85
  img_bytes = out_io.getvalue()
74
86
  images.append(img_bytes)
75
87
  if response_format == "url":
88
+
76
89
  def upload_file_with_retry(img_bytes, image_format, max_retries=3):
77
90
  ext = "jpg" if image_format.lower() in ("jpeg", "jpg") else "png"
78
91
  for attempt in range(max_retries):
79
92
  tmp_path = None
80
93
  try:
81
- with tempfile.NamedTemporaryFile(suffix=f".{ext}", delete=False) as tmp:
94
+ with tempfile.NamedTemporaryFile(
95
+ suffix=f".{ext}", delete=False
96
+ ) as tmp:
82
97
  tmp.write(img_bytes)
83
98
  tmp.flush()
84
99
  tmp_path = tmp.name
85
- with open(tmp_path, 'rb') as f:
100
+ with open(tmp_path, "rb") as f:
86
101
  files = {
87
- 'fileToUpload': (f'image.{ext}', f, f'image/{ext}')
102
+ "fileToUpload": (f"image.{ext}", f, f"image/{ext}")
88
103
  }
89
- data = {
90
- 'reqtype': 'fileupload',
91
- 'json': 'true'
92
- }
93
- headers = {'User-Agent': agent.random()}
104
+ data = {"reqtype": "fileupload", "json": "true"}
105
+ headers = {"User-Agent": agent.random()}
94
106
  if attempt > 0:
95
- headers['Connection'] = 'close'
96
- resp = requests.post("https://catbox.moe/user/api.php", files=files, data=data, headers=headers, timeout=timeout)
107
+ headers["Connection"] = "close"
108
+ resp = requests.post(
109
+ "https://catbox.moe/user/api.php",
110
+ files=files,
111
+ data=data,
112
+ headers=headers,
113
+ timeout=timeout,
114
+ )
97
115
  if resp.status_code == 200 and resp.text.strip():
98
116
  text = resp.text.strip()
99
- if text.startswith('http'):
117
+ if text.startswith("http"):
100
118
  return text
101
119
  try:
102
120
  result = resp.json()
103
121
  if "url" in result:
104
122
  return result["url"]
105
123
  except Exception:
106
- if 'http' in text:
124
+ if "http" in text:
107
125
  return text
108
126
  except Exception:
109
127
  if attempt < max_retries - 1:
@@ -115,22 +133,27 @@ class Images(BaseImages):
115
133
  except Exception:
116
134
  pass
117
135
  return None
136
+
118
137
  def upload_file_alternative(img_bytes, image_format):
119
138
  try:
120
- ext = "jpg" if image_format.lower() in ("jpeg", "jpg") else "png"
121
- with tempfile.NamedTemporaryFile(suffix=f".{ext}", delete=False) as tmp:
139
+ ext = (
140
+ "jpg" if image_format.lower() in ("jpeg", "jpg") else "png"
141
+ )
142
+ with tempfile.NamedTemporaryFile(
143
+ suffix=f".{ext}", delete=False
144
+ ) as tmp:
122
145
  tmp.write(img_bytes)
123
146
  tmp.flush()
124
147
  tmp_path = tmp.name
125
148
  try:
126
149
  if not os.path.isfile(tmp_path):
127
150
  return None
128
- with open(tmp_path, 'rb') as img_file:
129
- files = {'file': img_file}
130
- alt_resp = requests.post('https://0x0.st', files=files)
151
+ with open(tmp_path, "rb") as img_file:
152
+ files = {"file": img_file}
153
+ alt_resp = requests.post("https://0x0.st", files=files)
131
154
  alt_resp.raise_for_status()
132
155
  image_url = alt_resp.text.strip()
133
- if not image_url.startswith('http'):
156
+ if not image_url.startswith("http"):
134
157
  return None
135
158
  return image_url
136
159
  except Exception:
@@ -142,32 +165,36 @@ class Images(BaseImages):
142
165
  pass
143
166
  except Exception:
144
167
  return None
168
+
145
169
  uploaded_url = upload_file_with_retry(img_bytes, image_format)
146
170
  if not uploaded_url:
147
171
  uploaded_url = upload_file_alternative(img_bytes, image_format)
148
172
  if uploaded_url:
149
173
  urls.append(uploaded_url)
150
174
  else:
151
- raise RuntimeError("Failed to upload image to catbox.moe using all available methods")
175
+ raise RuntimeError(
176
+ "Failed to upload image to catbox.moe using all available methods"
177
+ )
152
178
  result_data = []
153
179
  if response_format == "url":
154
180
  for url in urls:
155
181
  result_data.append(ImageData(url=url))
156
182
  elif response_format == "b64_json":
157
183
  import base64
184
+
158
185
  for img in images:
159
186
  b64 = base64.b64encode(img).decode("utf-8")
160
187
  result_data.append(ImageData(b64_json=b64))
161
188
  else:
162
189
  raise ValueError("response_format must be 'url' or 'b64_json'")
163
190
  from time import time as _time
164
- return ImageResponse(
165
- created=int(_time()),
166
- data=result_data
167
- )
191
+
192
+ return ImageResponse(created=int(_time()), data=result_data)
193
+
168
194
 
169
195
  class MagicStudioAI(TTICompatibleProvider):
170
196
  AVAILABLE_MODELS = ["magicstudio"]
197
+
171
198
  def __init__(self):
172
199
  self.api_endpoint = "https://ai-api.magicstudio.com/api/ai-art-generator"
173
200
  self.session = requests.Session()
@@ -182,15 +209,19 @@ class MagicStudioAI(TTICompatibleProvider):
182
209
  }
183
210
  self.session.headers.update(self.headers)
184
211
  self.images = Images(self)
212
+
185
213
  @property
186
214
  def models(self):
187
215
  class _ModelList:
188
216
  def list(inner_self):
189
217
  return type(self).AVAILABLE_MODELS
218
+
190
219
  return _ModelList()
191
220
 
221
+
192
222
  if __name__ == "__main__":
193
223
  from rich import print
224
+
194
225
  client = MagicStudioAI()
195
226
  response = client.images.create(
196
227
  prompt="A cool cyberpunk city at night",
@@ -1,6 +1,9 @@
1
1
  import requests
2
2
  from typing import Optional, List, Dict, Any
3
- from webscout.Provider.TTI.utils import ImageData, ImageResponse
3
+ from webscout.Provider.TTI.utils import (
4
+ ImageData,
5
+ ImageResponse
6
+ )
4
7
  from webscout.Provider.TTI.base import TTICompatibleProvider, BaseImages
5
8
  from io import BytesIO
6
9
  import os
@@ -14,11 +17,13 @@ try:
14
17
  except ImportError:
15
18
  Image = None
16
19
 
20
+
17
21
  class Images(BaseImages):
18
22
  def __init__(self, client):
19
23
  self._client = client
20
24
 
21
- def create(self,
25
+ def create(
26
+ self,
22
27
  model: str,
23
28
  prompt: str,
24
29
  n: int = 1,
@@ -29,7 +34,7 @@ class Images(BaseImages):
29
34
  aspect_ratio: str = "1:1",
30
35
  timeout: int = 60,
31
36
  image_format: str = "jpeg",
32
- **kwargs
37
+ **kwargs,
33
38
  ) -> ImageResponse:
34
39
  """
35
40
  image_format: "png" or "jpeg"
@@ -46,32 +51,35 @@ class Images(BaseImages):
46
51
  for attempt in range(max_retries):
47
52
  tmp_path = None
48
53
  try:
49
- with tempfile.NamedTemporaryFile(suffix=f".{ext}", delete=False) as tmp:
54
+ with tempfile.NamedTemporaryFile(
55
+ suffix=f".{ext}", delete=False
56
+ ) as tmp:
50
57
  tmp.write(img_bytes)
51
58
  tmp.flush()
52
59
  tmp_path = tmp.name
53
- with open(tmp_path, 'rb') as f:
54
- files = {
55
- 'fileToUpload': (f'image.{ext}', f, f'image/{ext}')
56
- }
57
- data = {
58
- 'reqtype': 'fileupload',
59
- 'json': 'true'
60
- }
61
- headers = {'User-Agent': agent.random()}
60
+ with open(tmp_path, "rb") as f:
61
+ files = {"fileToUpload": (f"image.{ext}", f, f"image/{ext}")}
62
+ data = {"reqtype": "fileupload", "json": "true"}
63
+ headers = {"User-Agent": agent.random()}
62
64
  if attempt > 0:
63
- headers['Connection'] = 'close'
64
- resp = requests.post("https://catbox.moe/user/api.php", files=files, data=data, headers=headers, timeout=timeout)
65
+ headers["Connection"] = "close"
66
+ resp = requests.post(
67
+ "https://catbox.moe/user/api.php",
68
+ files=files,
69
+ data=data,
70
+ headers=headers,
71
+ timeout=timeout,
72
+ )
65
73
  if resp.status_code == 200 and resp.text.strip():
66
74
  text = resp.text.strip()
67
- if text.startswith('http'):
75
+ if text.startswith("http"):
68
76
  return text
69
77
  try:
70
78
  result = resp.json()
71
79
  if "url" in result:
72
80
  return result["url"]
73
81
  except json.JSONDecodeError:
74
- if 'http' in text:
82
+ if "http" in text:
75
83
  return text
76
84
  except Exception:
77
85
  if attempt < max_retries - 1:
@@ -94,12 +102,12 @@ class Images(BaseImages):
94
102
  try:
95
103
  if not os.path.isfile(tmp_path):
96
104
  return None
97
- with open(tmp_path, 'rb') as img_file:
98
- files = {'file': img_file}
99
- response = requests.post('https://0x0.st', files=files)
105
+ with open(tmp_path, "rb") as img_file:
106
+ files = {"file": img_file}
107
+ response = requests.post("https://0x0.st", files=files)
100
108
  response.raise_for_status()
101
109
  image_url = response.text.strip()
102
- if not image_url.startswith('http'):
110
+ if not image_url.startswith("http"):
103
111
  return None
104
112
  return image_url
105
113
  except Exception:
@@ -117,11 +125,11 @@ class Images(BaseImages):
117
125
  resp = self._client.session.post(
118
126
  self._client.api_endpoint,
119
127
  json=payload,
120
- timeout=timeout
128
+ timeout=timeout,
121
129
  )
122
130
  resp.raise_for_status()
123
131
  # Piclumen returns image/jpeg directly
124
- if resp.headers.get('content-type') == 'image/jpeg':
132
+ if resp.headers.get("content-type") == "image/jpeg":
125
133
  img_bytes = resp.content
126
134
  # Convert to png or jpeg in memory
127
135
  with BytesIO(img_bytes) as input_io:
@@ -141,7 +149,9 @@ class Images(BaseImages):
141
149
  if uploaded_url:
142
150
  urls.append(uploaded_url)
143
151
  else:
144
- raise RuntimeError("Failed to upload image to catbox.moe using all available methods")
152
+ raise RuntimeError(
153
+ "Failed to upload image to catbox.moe using all available methods"
154
+ )
145
155
  else:
146
156
  raise RuntimeError("No image data received from Piclumen")
147
157
 
@@ -151,6 +161,7 @@ class Images(BaseImages):
151
161
  result_data.append(ImageData(url=url))
152
162
  elif response_format == "b64_json":
153
163
  import base64
164
+
154
165
  for img in images:
155
166
  b64 = base64.b64encode(img).decode("utf-8")
156
167
  result_data.append(ImageData(b64_json=b64))
@@ -158,15 +169,12 @@ class Images(BaseImages):
158
169
  raise ValueError("response_format must be 'url' or 'b64_json'")
159
170
 
160
171
  from time import time as _time
161
- return ImageResponse(
162
- created=int(_time()),
163
- data=result_data
164
- )
172
+
173
+ return ImageResponse(created=int(_time()), data=result_data)
174
+
165
175
 
166
176
  class PiclumenAI(TTICompatibleProvider):
167
- AVAILABLE_MODELS = [
168
- "piclumen-v1"
169
- ]
177
+ AVAILABLE_MODELS = ["piclumen-v1"]
170
178
 
171
179
  def __init__(self):
172
180
  self.api_endpoint = "https://s9.piclumen.art/comfy/api/generate-image"
@@ -188,10 +196,13 @@ class PiclumenAI(TTICompatibleProvider):
188
196
  class _ModelList:
189
197
  def list(inner_self):
190
198
  return type(self).AVAILABLE_MODELS
199
+
191
200
  return _ModelList()
192
201
 
202
+
193
203
  if __name__ == "__main__":
194
204
  from rich import print
205
+
195
206
  client = PiclumenAI()
196
207
  response = client.images.create(
197
208
  model="piclumen-v1",
@@ -200,4 +211,4 @@ if __name__ == "__main__":
200
211
  n=2,
201
212
  timeout=30,
202
213
  )
203
- print(response)
214
+ print(response)