webscout 7.3__py3-none-any.whl → 7.5__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 (62) hide show
  1. webscout/Provider/AISEARCH/__init__.py +4 -3
  2. webscout/Provider/AISEARCH/genspark_search.py +208 -0
  3. webscout/Provider/AllenAI.py +282 -0
  4. webscout/Provider/C4ai.py +414 -0
  5. webscout/Provider/Cloudflare.py +18 -21
  6. webscout/Provider/DeepSeek.py +3 -32
  7. webscout/Provider/Deepinfra.py +52 -44
  8. webscout/Provider/ElectronHub.py +634 -0
  9. webscout/Provider/GithubChat.py +362 -0
  10. webscout/Provider/Glider.py +7 -41
  11. webscout/Provider/HeckAI.py +217 -0
  12. webscout/Provider/HuggingFaceChat.py +462 -0
  13. webscout/Provider/Jadve.py +49 -63
  14. webscout/Provider/Marcus.py +7 -50
  15. webscout/Provider/Netwrck.py +6 -53
  16. webscout/Provider/PI.py +106 -93
  17. webscout/Provider/Perplexitylabs.py +395 -0
  18. webscout/Provider/Phind.py +29 -3
  19. webscout/Provider/QwenLM.py +7 -61
  20. webscout/Provider/TTI/__init__.py +1 -0
  21. webscout/Provider/TTI/aiarta/__init__.py +2 -0
  22. webscout/Provider/TTI/aiarta/async_aiarta.py +482 -0
  23. webscout/Provider/TTI/aiarta/sync_aiarta.py +409 -0
  24. webscout/Provider/TTI/piclumen/__init__.py +23 -0
  25. webscout/Provider/TTI/piclumen/async_piclumen.py +268 -0
  26. webscout/Provider/TTI/piclumen/sync_piclumen.py +233 -0
  27. webscout/Provider/TextPollinationsAI.py +3 -2
  28. webscout/Provider/TwoAI.py +200 -0
  29. webscout/Provider/Venice.py +200 -0
  30. webscout/Provider/WiseCat.py +1 -18
  31. webscout/Provider/Youchat.py +1 -1
  32. webscout/Provider/__init__.py +25 -2
  33. webscout/Provider/akashgpt.py +315 -0
  34. webscout/Provider/chatglm.py +5 -5
  35. webscout/Provider/copilot.py +416 -0
  36. webscout/Provider/flowith.py +181 -0
  37. webscout/Provider/freeaichat.py +251 -221
  38. webscout/Provider/granite.py +17 -53
  39. webscout/Provider/koala.py +9 -1
  40. webscout/Provider/llamatutor.py +6 -46
  41. webscout/Provider/llmchat.py +7 -46
  42. webscout/Provider/multichat.py +29 -91
  43. webscout/Provider/yep.py +4 -24
  44. webscout/exceptions.py +19 -9
  45. webscout/update_checker.py +55 -93
  46. webscout/version.py +1 -1
  47. webscout-7.5.dist-info/LICENSE.md +146 -0
  48. {webscout-7.3.dist-info → webscout-7.5.dist-info}/METADATA +46 -172
  49. {webscout-7.3.dist-info → webscout-7.5.dist-info}/RECORD +52 -42
  50. webscout/Local/__init__.py +0 -10
  51. webscout/Local/_version.py +0 -3
  52. webscout/Local/formats.py +0 -747
  53. webscout/Local/model.py +0 -1368
  54. webscout/Local/samplers.py +0 -125
  55. webscout/Local/thread.py +0 -539
  56. webscout/Local/ui.py +0 -401
  57. webscout/Local/utils.py +0 -388
  58. webscout/Provider/dgaf.py +0 -214
  59. webscout-7.3.dist-info/LICENSE.md +0 -211
  60. {webscout-7.3.dist-info → webscout-7.5.dist-info}/WHEEL +0 -0
  61. {webscout-7.3.dist-info → webscout-7.5.dist-info}/entry_points.txt +0 -0
  62. {webscout-7.3.dist-info → webscout-7.5.dist-info}/top_level.txt +0 -0
webscout/Provider/yep.py CHANGED
@@ -12,7 +12,6 @@ from webscout.AIutel import Conversation
12
12
  from webscout.AIutel import AwesomePrompts
13
13
  from webscout.AIbase import Provider
14
14
  from webscout import WEBS, exceptions
15
- from webscout.Litlogger import Logger, LogFormat
16
15
  from webscout.litagent import LitAgent
17
16
 
18
17
 
@@ -39,14 +38,13 @@ class YEPCHAT(Provider):
39
38
  act: str = None,
40
39
  model: str = "DeepSeek-R1-Distill-Qwen-32B",
41
40
  temperature: float = 0.6,
42
- top_p: float = 0.7,
43
- logging: bool = False,
41
+ top_p: float = 0.7
44
42
  ):
45
43
  """
46
44
  Initializes the YEPCHAT provider with the specified parameters.
47
45
 
48
46
  Examples:
49
- >>> ai = YEPCHAT(logging=True)
47
+ >>> ai = YEPCHAT()
50
48
  >>> ai.ask("What's the weather today?")
51
49
  Sends a prompt to the Yep API and returns the response.
52
50
 
@@ -85,7 +83,7 @@ class YEPCHAT(Provider):
85
83
  "Sec-CH-UA-Platform": '"Windows"',
86
84
  "User-Agent": self.agent.random(), # Use LitAgent to generate a random user agent
87
85
  }
88
- self.cookies = {"__Host-session": uuid.uuid4().hex}
86
+ self.cookies = {"__Host-session": uuid.uuid4().hex, '__cf_bm': uuid.uuid4().hex}
89
87
 
90
88
  self.__available_optimizers = (
91
89
  method
@@ -106,9 +104,6 @@ class YEPCHAT(Provider):
106
104
 
107
105
  self.knowledge_cutoff = "December 2023"
108
106
 
109
- # Initialize logger
110
- self.logger = Logger(name="YEPCHAT", format=LogFormat.MODERN_EMOJI) if logging else None
111
-
112
107
  def ask(
113
108
  self,
114
109
  prompt: str,
@@ -128,9 +123,6 @@ class YEPCHAT(Provider):
128
123
  >>> ai.ask("Tell me a joke", stream=True)
129
124
  Streams the response from the Yep API.
130
125
  """
131
- if self.logger:
132
- self.logger.debug(f"ask() called with prompt: {prompt}")
133
-
134
126
  conversation_prompt = self.conversation.gen_complete_prompt(prompt)
135
127
  if optimizer:
136
128
  if optimizer in self.__available_optimizers:
@@ -138,8 +130,6 @@ class YEPCHAT(Provider):
138
130
  conversation_prompt if conversationally else prompt
139
131
  )
140
132
  else:
141
- if self.logger:
142
- self.logger.error(f"Invalid optimizer: {optimizer}")
143
133
  raise Exception(
144
134
  f"Optimizer is not one of {self.__available_optimizers}"
145
135
  )
@@ -157,8 +147,6 @@ class YEPCHAT(Provider):
157
147
  try:
158
148
  with self.session.post(self.chat_endpoint, headers=self.headers, cookies=self.cookies, json=data, stream=True, timeout=self.timeout) as response:
159
149
  if not response.ok:
160
- if self.logger:
161
- self.logger.error(f"Failed to generate response: {response.status_code} {response.reason}")
162
150
  raise exceptions.FailedToGenerateResponseError(
163
151
  f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
164
152
  )
@@ -183,13 +171,9 @@ class YEPCHAT(Provider):
183
171
  resp = dict(text=content)
184
172
  yield resp if raw else resp
185
173
  except json.JSONDecodeError:
186
- if self.logger:
187
- self.logger.warning("JSONDecodeError encountered.")
188
174
  pass
189
175
  self.conversation.update_chat_history(prompt, streaming_text)
190
176
  except Exception as e:
191
- if self.logger:
192
- self.logger.error(f"Request failed: {e}")
193
177
  raise exceptions.FailedToGenerateResponseError(f"Request failed: {e}")
194
178
 
195
179
  def for_non_stream():
@@ -217,9 +201,6 @@ class YEPCHAT(Provider):
217
201
  >>> ai.chat("What's the weather today?", stream=True)
218
202
  Streams the chat response from the Yep API.
219
203
  """
220
- if self.logger:
221
- self.logger.debug(f"chat() called with prompt: {prompt}")
222
-
223
204
  def for_stream():
224
205
  for response in self.ask(
225
206
  prompt, True, optimizer=optimizer, conversationally=conversationally
@@ -255,8 +236,7 @@ class YEPCHAT(Provider):
255
236
  if __name__ == "__main__":
256
237
  from rich import print
257
238
 
258
- ai = YEPCHAT(logging=False)
259
-
239
+ ai = YEPCHAT(model="DeepSeek-R1-Distill-Qwen-32B")
260
240
  response = ai.chat("how many r in 'strawberry'", stream=True)
261
241
  for chunk in response:
262
242
  print(chunk, end="", flush=True)
webscout/exceptions.py CHANGED
@@ -11,7 +11,7 @@ class WebscoutE(Exception):
11
11
  pass
12
12
 
13
13
 
14
- class APIConnectionError(Exception):
14
+ class APIConnectionError(WebscoutE):
15
15
  """
16
16
  Exception raised when there are issues connecting to an API.
17
17
 
@@ -21,7 +21,17 @@ class APIConnectionError(Exception):
21
21
  pass
22
22
 
23
23
 
24
- class RatelimitE(Exception):
24
+ class AuthenticationError(WebscoutE):
25
+ """
26
+ Exception raised when authentication to a service fails.
27
+
28
+ This exception is raised when the provided credentials are invalid or expired.
29
+ It indicates that the application cannot authenticate with the service.
30
+ """
31
+ pass
32
+
33
+
34
+ class RatelimitE(WebscoutE):
25
35
  """
26
36
  Exception raised when an API rate limit is exceeded.
27
37
 
@@ -31,7 +41,7 @@ class RatelimitE(Exception):
31
41
  pass
32
42
 
33
43
 
34
- class ConversationLimitException(Exception):
44
+ class ConversationLimitException(WebscoutE):
35
45
  """
36
46
  Exception raised when a conversation limit is exceeded.
37
47
 
@@ -41,7 +51,7 @@ class ConversationLimitException(Exception):
41
51
  pass
42
52
 
43
53
 
44
- class TimeoutE(Exception):
54
+ class TimeoutE(WebscoutE):
45
55
  """
46
56
  Exception raised when a request to an API times out.
47
57
 
@@ -51,7 +61,7 @@ class TimeoutE(Exception):
51
61
  pass
52
62
 
53
63
 
54
- class FailedToGenerateResponseError(Exception):
64
+ class FailedToGenerateResponseError(WebscoutE):
55
65
  """
56
66
  Exception raised when a provider fails to generate a response.
57
67
 
@@ -61,7 +71,7 @@ class FailedToGenerateResponseError(Exception):
61
71
  pass
62
72
 
63
73
 
64
- class AllProvidersFailure(Exception):
74
+ class AllProvidersFailure(WebscoutE):
65
75
  """
66
76
  Exception raised when all providers fail to generate a response.
67
77
 
@@ -71,7 +81,7 @@ class AllProvidersFailure(Exception):
71
81
  pass
72
82
 
73
83
 
74
- class FacebookInvalidCredentialsException(Exception):
84
+ class FacebookInvalidCredentialsException(WebscoutE):
75
85
  """
76
86
  Exception raised when Facebook credentials are invalid.
77
87
 
@@ -81,7 +91,7 @@ class FacebookInvalidCredentialsException(Exception):
81
91
  pass
82
92
 
83
93
 
84
- class FacebookRegionBlocked(Exception):
94
+ class FacebookRegionBlocked(WebscoutE):
85
95
  """
86
96
  Exception raised when Facebook access is blocked due to region restrictions.
87
97
 
@@ -91,7 +101,7 @@ class FacebookRegionBlocked(Exception):
91
101
  pass
92
102
 
93
103
 
94
- class ModelUnloadedException(Exception):
104
+ class ModelUnloadedException(WebscoutE):
95
105
  """
96
106
  Exception raised when a model is unloaded.
97
107
 
@@ -1,43 +1,28 @@
1
1
  """
2
- Ayy, check it out! 👀
2
+ Webscout Update Checker
3
3
  >>> from webscout import check_for_updates
4
- >>> check_for_updates()
5
- 'Yo, new Webscout version just dropped: 2.0.0! 🔥
6
- Level up with: `pip install --upgrade webscout`'
4
+ >>> result = check_for_updates()
5
+ >>> print(result)
6
+ 'New Webscout version available: 2.0.0 - Update with: pip install --upgrade webscout'
7
7
  """
8
8
 
9
- import subprocess
10
9
  import sys
11
10
  import os
12
- from typing import Optional
11
+ from typing import Optional, Tuple, Dict, Any, Literal, Union
13
12
 
14
13
  import requests
15
14
  from packaging import version
16
- import re
17
-
18
- from webscout.Litlogger import Logger
19
15
  from importlib.metadata import version as get_package_version
20
16
  from importlib.metadata import PackageNotFoundError
21
- from importlib.metadata import metadata as get_package_metadata
22
-
23
- # Setting up that clean logger format, no cap! 💯
24
- CUSTOM_FORMAT = """{message}"""
25
17
 
26
- logger = Logger(
27
- name="WebscoutUpdate",
28
- format=CUSTOM_FORMAT,
29
- )
18
+ # Version comparison result type
19
+ VersionCompareResult = Literal[-1, 0, 1]
30
20
 
31
21
  def get_installed_version() -> Optional[str]:
32
- """Yo, let's check what version you're running! 🔍
33
-
34
- What this function's all about:
35
- - Checking your setup real quick 💨
36
- - Getting them version deets 📱
37
- - Handling any problems like a boss 💪
22
+ """Get the currently installed version of webscout.
38
23
 
39
24
  Returns:
40
- Optional[str]: Your version number or None if we can't find it
25
+ Optional[str]: The installed version string or None if not found
41
26
 
42
27
  Examples:
43
28
  >>> version = get_installed_version()
@@ -48,19 +33,14 @@ def get_installed_version() -> Optional[str]:
48
33
  return get_package_version('webscout')
49
34
  except PackageNotFoundError:
50
35
  return None
51
- except Exception as e:
36
+ except Exception:
52
37
  return None
53
38
 
54
39
  def get_pypi_version() -> Optional[str]:
55
- """Let's see what's fresh on PyPI! 🚀
56
-
57
- This function's vibe:
58
- - Hitting up PyPI for the latest drop 🌐
59
- - Keeping it smooth with timeout handling ⚡
60
- - Making sure we get good data fr fr 💯
40
+ """Get the latest version available on PyPI.
61
41
 
62
42
  Returns:
63
- Optional[str]: Latest version or None if something's not right
43
+ Optional[str]: The latest version string or None if retrieval failed
64
44
 
65
45
  Examples:
66
46
  >>> latest = get_pypi_version()
@@ -73,24 +53,20 @@ def get_pypi_version() -> Optional[str]:
73
53
  timeout=10
74
54
  )
75
55
  response.raise_for_status()
76
- return response.json()['info']['version']
77
- except requests.RequestException as e:
78
- pass
79
- except (KeyError, ValueError) as e:
80
- pass
81
- except Exception as e:
82
- pass
83
- return None
56
+ data: Dict[str, Any] = response.json()
57
+ return data['info']['version']
58
+ except (requests.RequestException, KeyError, ValueError, Exception):
59
+ return None
84
60
 
85
- def version_compare(v1: str, v2: str) -> int:
86
- """Time to compare these versions! 💪
61
+ def version_compare(v1: str, v2: str) -> VersionCompareResult:
62
+ """Compare two version strings.
87
63
 
88
64
  Args:
89
- v1: First version we checking
90
- v2: Second version to compare with
65
+ v1: First version string
66
+ v2: Second version string to compare with
91
67
 
92
68
  Returns:
93
- int: -1 if v1's older, 1 if v1's newer, 0 if they twins
69
+ VersionCompareResult: -1 if v1 < v2, 1 if v1 > v2, 0 if equal
94
70
 
95
71
  Examples:
96
72
  >>> version_compare('1.0.0', '2.0.0')
@@ -104,71 +80,57 @@ def version_compare(v1: str, v2: str) -> int:
104
80
  if version1 > version2:
105
81
  return 1
106
82
  return 0
107
- except version.InvalidVersion as e:
108
- pass
109
- return 0
110
- except Exception as e:
111
- pass
83
+ except (version.InvalidVersion, Exception):
112
84
  return 0
113
85
 
114
- def display_version_info(installed: Optional[str], latest: Optional[str]) -> None:
115
- """Let's break down your version status! 📱
116
-
117
- What we doing here:
118
- - Comparing your version with the latest drop 🔄
119
- - Letting you know if you need to level up ⬆️
120
- - Keeping you in the loop with style 💯
86
+ def get_update_message(installed: str, latest: str) -> Optional[str]:
87
+ """Generate appropriate update message based on version comparison.
121
88
 
122
89
  Args:
123
- installed: What you running rn
124
- latest: What's fresh out there
90
+ installed: Currently installed version
91
+ latest: Latest available version
92
+
93
+ Returns:
94
+ Optional[str]: Update message if needed, None if already on latest version
125
95
 
126
96
  Examples:
127
- >>> display_version_info('1.0.0', '2.0.0')
128
- 'Yo, new Webscout version just dropped: 2.0.0! 🔥'
97
+ >>> get_update_message('1.0.0', '2.0.0')
98
+ 'New Webscout version available: 2.0.0 - Update with: pip install --upgrade webscout'
129
99
  """
130
- if installed:
131
- pass
132
-
133
- if latest and installed:
134
- comparison_result = version_compare(installed, latest)
135
- if comparison_result < 0:
136
- logger.warning(
137
- f"Yo, new Webscout version just dropped: {latest}! 🔥\n"
138
- f"Level up with: `pip install --upgrade webscout`"
139
- )
140
- elif comparison_result > 0:
141
- logger.success("You already got the latest version, no cap! 💯")
142
-
143
- def check_for_updates() -> None:
144
- """Time to check if you're running the latest! 🚀
145
-
146
- What we doing:
147
- - Peeking at your current setup 📱
148
- - Checking what's new out there 🌐
149
- - Keeping you updated fr fr ⚡
100
+ comparison_result = version_compare(installed, latest)
101
+ if comparison_result < 0:
102
+ return f"New Webscout version available: {latest} - Update with: pip install --upgrade webscout"
103
+ elif comparison_result > 0:
104
+ return f"You're running a development version ({installed}) ahead of latest release ({latest})"
105
+ return None # Already on the latest version
106
+
107
+ def check_for_updates() -> Optional[str]:
108
+ """Check if a newer version of Webscout is available.
109
+
110
+ Returns:
111
+ Optional[str]: Update message if newer version exists, None otherwise
150
112
 
151
113
  Examples:
152
- >>> check_for_updates()
153
- # We got you with them version checks fam!
114
+ >>> result = check_for_updates()
115
+ >>> print(result)
116
+ 'New Webscout version available: 2.0.0 - Update with: pip install --upgrade webscout'
154
117
  """
155
118
  installed_version = get_installed_version()
156
- latest_version = get_pypi_version()
157
-
158
119
  if not installed_version:
159
- pass
160
- return
120
+ return None
161
121
 
122
+ latest_version = get_pypi_version()
162
123
  if not latest_version:
163
- pass
164
- return
124
+ return None
165
125
 
166
- display_version_info(installed_version, latest_version)
126
+ return get_update_message(installed_version, latest_version)
167
127
 
168
128
  if __name__ == "__main__":
169
129
  try:
170
- check_for_updates()
130
+ update_message = check_for_updates()
131
+ if update_message:
132
+ print(update_message)
171
133
  except KeyboardInterrupt:
172
- logger.warning("Update check got cancelled, no worries fam! 🤚")
134
+ print("Update check canceled")
173
135
  except Exception as e:
174
- logger.error(f"Uh oh, something went wrong: {str(e)} 😔")
136
+ print(f"Update check failed: {str(e)}")
webscout/version.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "7.3"
1
+ __version__ = "7.5"
2
2
  __prog__ = "webscout"
@@ -0,0 +1,146 @@
1
+ Apache License
2
+ Version 2.0, March 2025
3
+ Webscout License
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work.
38
+
39
+ "Derivative Works" shall mean any work, whether in Source or Object
40
+ form, that is based on (or derived from) the Work and for which the
41
+ editorial revisions, annotations, elaborations, or other modifications
42
+ represent, as a whole, an original work of authorship.
43
+
44
+ "Contribution" shall mean any work of authorship, including
45
+ the original version of the Work and any modifications or additions
46
+ to that Work or Derivative Works thereof, that is intentionally
47
+ submitted to Licensor for inclusion in the Work by the copyright owner
48
+ or by an individual or Legal Entity authorized to submit on behalf of
49
+ the copyright owner.
50
+
51
+ 2. Grant of Copyright License. Subject to the terms and conditions of
52
+ this License, each Contributor hereby grants to You a perpetual,
53
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
54
+ copyright license to reproduce, prepare Derivative Works of,
55
+ publicly display, publicly perform, sublicense, and distribute the
56
+ Work and such Derivative Works in Source or Object form.
57
+
58
+ 3. Grant of Patent License. Subject to the terms and conditions of
59
+ this License, each Contributor hereby grants to You a perpetual,
60
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
61
+ (except as stated in this section) patent license to make, have made,
62
+ use, offer to sell, sell, import, and otherwise transfer the Work,
63
+ where such license applies only to those patent claims licensable
64
+ by such Contributor that are necessarily infringed by their
65
+ Contribution(s) alone or by combination of their Contribution(s)
66
+ with the Work to which such Contribution(s) was submitted.
67
+
68
+ 4. Redistribution. You may reproduce and distribute copies of the
69
+ Work or Derivative Works thereof in any medium, with or without
70
+ modifications, and in Source or Object form, provided that You
71
+ meet the following conditions:
72
+
73
+ (a) You must give any other recipients of the Work or
74
+ Derivative Works a copy of this License; and
75
+
76
+ (b) You must cause any modified files to carry prominent notices
77
+ stating that You changed the files; and
78
+
79
+ (c) You must retain, in the Source form of any Derivative Works
80
+ that You distribute, all copyright, patent, trademark, and
81
+ attribution notices from the Source form of the Work; and
82
+
83
+ (d) If the Work includes a "NOTICE" text file as part of its
84
+ distribution, then any Derivative Works that You distribute must
85
+ include a readable copy of the attribution notices contained
86
+ within such NOTICE file; and
87
+
88
+ (e) You must include the following attribution notice prominently
89
+ displayed in any Derivative Works:
90
+ "Based on Webscout (https://github.com/webscout)"
91
+
92
+ 5. API Usage and Third-Party Services. When using the APIs and services
93
+ accessed through this Work, you must:
94
+
95
+ (a) Comply with all terms of service of the respective API providers; and
96
+
97
+ (b) Maintain appropriate attribution and licenses for third-party services; and
98
+
99
+ (c) Be responsible for obtaining any necessary permissions or licenses; and
100
+
101
+ (d) Not use the Work in any way that could damage or overload third-party services.
102
+
103
+ 6. Submission of Contributions. Unless You explicitly state otherwise,
104
+ any Contribution intentionally submitted for inclusion in the Work
105
+ by You to the Licensor shall be under the terms and conditions of
106
+ this License, without any additional terms or conditions.
107
+
108
+ 7. Trademarks. This License does not grant permission to use the trade
109
+ names, trademarks, service marks, or product names of the Licensor,
110
+ except as required for reasonable and customary use in describing the
111
+ origin of the Work and reproducing the content of the NOTICE file.
112
+
113
+ 8. Disclaimer of Warranty. Unless required by applicable law or
114
+ agreed to in writing, Licensor provides the Work (and each
115
+ Contributor provides its Contributions) on an "AS IS" BASIS,
116
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
117
+ implied, including, without limitation, any warranties or conditions
118
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
119
+ PARTICULAR PURPOSE. You are solely responsible for determining the
120
+ appropriateness of using or redistributing the Work and assume any
121
+ risks associated with Your exercise of permissions under this License.
122
+
123
+ 9. Limitation of Liability. In no event and under no legal theory,
124
+ whether in tort (including negligence), contract, or otherwise,
125
+ unless required by applicable law (such as deliberate and grossly
126
+ negligent acts) or agreed to in writing, shall any Contributor be
127
+ liable to You for damages, including any direct, indirect, special,
128
+ incidental, consequential, or exemplary damages of any character
129
+ arising as a result of this License or out of the use or inability
130
+ to use the Work.
131
+
132
+ END OF TERMS AND CONDITIONS
133
+
134
+ Copyright 2024-2025 Webscout Contributors
135
+
136
+ Licensed under the Apache License, Version 2.0 (the "License");
137
+ you may not use this file except in compliance with the License.
138
+ You may obtain a copy of the License at
139
+
140
+ http://www.apache.org/licenses/LICENSE-2.0
141
+
142
+ Unless required by applicable law or agreed to in writing, software
143
+ distributed under the License is distributed on an "AS IS" BASIS,
144
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145
+ See the License for the specific language governing permissions and
146
+ limitations under the License.