jigsawstack 0.1__tar.gz

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.
@@ -0,0 +1,62 @@
1
+ Metadata-Version: 2.1
2
+ Name: jigsawstack
3
+ Version: 0.1
4
+ Summary: JigsawStack Python SDK
5
+ Home-page: https://github.com/jigsawstack/jigsawstack-py
6
+ Author: Narcisse
7
+ Author-email: hello@jigsawstack.com
8
+ Keywords: AI,AI Tooling
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Natural Language :: English
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3.7
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Requires-Python: >=3.7
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: requests>=2.31.0
22
+ Requires-Dist: typing_extensions
23
+
24
+ # JigsawStack Python SDK
25
+
26
+ ## Installation
27
+
28
+ To install JigsawStack Python SDK, simply execute the following command in a terminal:
29
+
30
+ ```
31
+ pip install jigsawstack
32
+ ```
33
+
34
+ ## Setup
35
+
36
+ First, you need to get an API key, which is available in the [JigsawStack Dashboard](https://jigsawstack.com).
37
+
38
+ ```py
39
+ from jigsawstack from JigsawStack
40
+
41
+ import os
42
+
43
+ ai = JigsawStack(api_key="your-api-key")
44
+ ```
45
+
46
+ ## Example
47
+
48
+ ```py
49
+ import os
50
+ from jigsawstack from JigsawStack
51
+
52
+
53
+ ai = JigsawStack(api_key="your-api-key")
54
+
55
+ params = {
56
+ "url": "https://rogilvkqloanxtvjfrkm.supabase.co/storage/v1/object/public/demo/Collabo%201080x842.jpg?t=2024-03-22T09%3A22%3A48.442Z"
57
+ }
58
+
59
+ result = ai.vision.vocr(params)
60
+
61
+ print(result)
62
+ ```
@@ -0,0 +1,39 @@
1
+ # JigsawStack Python SDK
2
+
3
+ ## Installation
4
+
5
+ To install JigsawStack Python SDK, simply execute the following command in a terminal:
6
+
7
+ ```
8
+ pip install jigsawstack
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ First, you need to get an API key, which is available in the [JigsawStack Dashboard](https://jigsawstack.com).
14
+
15
+ ```py
16
+ from jigsawstack from JigsawStack
17
+
18
+ import os
19
+
20
+ ai = JigsawStack(api_key="your-api-key")
21
+ ```
22
+
23
+ ## Example
24
+
25
+ ```py
26
+ import os
27
+ from jigsawstack from JigsawStack
28
+
29
+
30
+ ai = JigsawStack(api_key="your-api-key")
31
+
32
+ params = {
33
+ "url": "https://rogilvkqloanxtvjfrkm.supabase.co/storage/v1/object/public/demo/Collabo%201080x842.jpg?t=2024-03-22T09%3A22%3A48.442Z"
34
+ }
35
+
36
+ result = ai.vision.vocr(params)
37
+
38
+ print(result)
39
+ ```
@@ -0,0 +1,10 @@
1
+ import os
2
+ from ._client import JigsawStack
3
+
4
+ # Config vars
5
+ api_key = os.environ.get("JIGSAWSTACK_API_KEY", "")
6
+ api_url = os.environ.get("JIGSAWSTACK_API_URL", "https://api.jigsawstack.com")
7
+
8
+
9
+ # Create a global instance of the Web class
10
+ __all__ = ["JigsawStack"]
@@ -0,0 +1,52 @@
1
+
2
+ from . import resources
3
+ from typing import Union
4
+ from ._config import ClientConfig
5
+ import os
6
+
7
+
8
+ class JigsawStack:
9
+ audio: resources.Audio
10
+ vision : resources.Vision
11
+ prediction: resources.Prediction
12
+ sql: resources.SQL
13
+ file: resources.File
14
+ kv: resources.KV
15
+ translate: resources.Translate
16
+ web: resources.Web
17
+ sentiment: resources.Sentiment
18
+ validate: resources.Validate
19
+ summary: resources.Summary
20
+ search: resources.Search
21
+ api_key: str
22
+ api_url: str
23
+
24
+
25
+ def __init__(self, api_key: Union[str, None] = None, api_url: Union[str, None] = None) -> None:
26
+ if api_key is None:
27
+ api_key = os.environ.get("JIGSAWSTACK_API_KEY")
28
+
29
+ if api_key is None:
30
+ raise ValueError("The api_key client option must be set either by passing api_key to the client or by setting the JIGSAWSTACK_API_KEY environment variable")
31
+
32
+ if api_url is None:
33
+ api_url = os.environ.get("JIGSAWSTACK_API_URL")
34
+ if api_url is None:
35
+ api_url = f"https://api.jigsawstack.com/v1"
36
+
37
+ self.api_key = api_key
38
+ self.api_url = api_url
39
+
40
+
41
+ self.audio = resources.Audio(api_key=api_key, api_url=api_url)
42
+ self.web = resources.Web(api_key=api_key, api_url=api_url)
43
+ self.search = resources.Search(api_key=api_key, api_url=api_url)
44
+ self.sentiment = resources.Sentiment(api_key=api_key, api_url=api_url)
45
+ self.validate = resources.Validate(api_key=api_key, api_url=api_url)
46
+ self.summary = resources.Summary(api_key=api_key, api_url=api_url)
47
+ self.vision = resources.Vision(api_key=api_key, api_url=api_url)
48
+ self.prediction = resources.Prediction(api_key=api_key, api_url=api_url)
49
+ self.sql = resources.SQL(api_key=api_key, api_url=api_url)
50
+ self.file = resources.File(api_key=api_key, api_url=api_url)
51
+ self.kv = resources.KV(api_key=api_key, api_url=api_url)
52
+ self.translate = resources.Translate(api_key=api_key, api_url=api_url)
@@ -0,0 +1,8 @@
1
+ class ClientConfig:
2
+
3
+ base_url:str
4
+ api_key:str
5
+
6
+ def __init__(self, api_key: str, api_url: str):
7
+ self.api_key = api_key
8
+ self.api_url = api_url
@@ -0,0 +1,228 @@
1
+ """JigsawStack Exceptions module.
2
+
3
+ This module defines the base types for platform-wide error
4
+
5
+ """
6
+
7
+ from typing import Any, Dict, Union
8
+
9
+
10
+ class JigsawStackError(Exception):
11
+ """Base class for all errors raised by JigsawStack SDK.
12
+ This is the parent class of all exceptions (server side)
13
+ raised by the JigsawStack SDK. Developers can simply catch
14
+ this class and inspect its `code` to implement more specific
15
+ error handling. Note that for some client-side errors ie:
16
+ some method argument missing, a ValueError would be raised.
17
+
18
+ Args:
19
+ code: A string error indicating the HTTP status code
20
+ attributed to that Error.
21
+ message: A human-readable error message string.
22
+ suggested_action: A suggested action path to help the user.
23
+ error_type: Maps to the `type` field from the JigsawStack API
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ code: Union[str, int],
29
+ error_type: str,
30
+ message: str,
31
+ suggested_action: str,
32
+ ):
33
+ Exception.__init__(self, message)
34
+ self.code = code
35
+ self.message = message
36
+ self.suggested_action = suggested_action
37
+ self.error_type = error_type
38
+
39
+
40
+ class MissingApiKeyError(JigsawStackError):
41
+
42
+ def __init__(
43
+ self,
44
+ message: str,
45
+ error_type: str,
46
+ code: Union[str, int],
47
+ ):
48
+ suggested_action = """Include the following header
49
+ Authorization: Bearer YOUR_API_KEY in the request."""
50
+
51
+ message = "Missing API key in the authorization header."
52
+
53
+ JigsawStackError.__init__(
54
+ self,
55
+ message=message,
56
+ suggested_action=suggested_action,
57
+ code=code,
58
+ error_type=error_type,
59
+ )
60
+
61
+
62
+ class InvalidApiKeyError(JigsawStackError):
63
+
64
+
65
+ def __init__(
66
+ self,
67
+ message: str,
68
+ error_type: str,
69
+ code: Union[str, int],
70
+ ):
71
+ suggested_action = """Generate a new API key in the dashboard."""
72
+
73
+ JigsawStackError.__init__(
74
+ self,
75
+ message=message,
76
+ suggested_action=suggested_action,
77
+ code=code,
78
+ error_type=error_type,
79
+ )
80
+
81
+
82
+ class ValidationError(JigsawStackError):
83
+
84
+
85
+ def __init__(
86
+ self,
87
+ message: str,
88
+ error_type: str,
89
+ code: Union[str, int],
90
+ ):
91
+ default_message = """
92
+ The request body is missing one or more required fields."""
93
+
94
+ suggested_action = """Check the error message
95
+ to see the list of missing fields."""
96
+
97
+ if message == "":
98
+ message = default_message
99
+
100
+ JigsawStackError.__init__(
101
+ self,
102
+ code=code or "400",
103
+ message=message,
104
+ suggested_action=suggested_action,
105
+ error_type=error_type,
106
+ )
107
+
108
+
109
+ class MissingRequiredFieldsError(JigsawStackError):
110
+
111
+ def __init__(
112
+ self,
113
+ message: str,
114
+ error_type: str,
115
+ code: Union[str, int],
116
+ ):
117
+ default_message = """
118
+ The request body is missing one or more required fields."""
119
+
120
+ suggested_action = """Check the error message
121
+ to see the list of missing fields."""
122
+
123
+ if message == "":
124
+ message = default_message
125
+
126
+ JigsawStackError.__init__(
127
+ self,
128
+ code=code or "422",
129
+ message=message,
130
+ suggested_action=suggested_action,
131
+ error_type=error_type,
132
+ )
133
+
134
+
135
+ class ApplicationError(JigsawStackError):
136
+
137
+
138
+ def __init__(
139
+ self,
140
+ message: str,
141
+ error_type: str,
142
+ code: Union[str, int],
143
+ ):
144
+ default_message = """
145
+ Something went wrong."""
146
+
147
+ suggested_action = """Contact JigsawStack support."""
148
+
149
+ if message == "":
150
+ message = default_message
151
+
152
+ JigsawStackError.__init__(
153
+ self,
154
+ code=code or "500",
155
+ message=message,
156
+ suggested_action=suggested_action,
157
+ error_type=error_type,
158
+ )
159
+
160
+
161
+ # Dict with error code -> error type mapping
162
+ ERRORS: Dict[str, Dict[str, Any]] = {
163
+ "400": {"validation_error": ValidationError},
164
+ "422": {
165
+ "missing_required_fields": MissingRequiredFieldsError,
166
+ "validation_error": ValidationError,
167
+ },
168
+ "401": {"missing_api_key": MissingApiKeyError},
169
+ "403": {"invalid_api_key": InvalidApiKeyError},
170
+ "500": {"application_error": ApplicationError},
171
+ }
172
+
173
+
174
+ def raise_for_code_and_type(
175
+ code: Union[str, int], error_type: str, message: str
176
+ ) -> None:
177
+ """Raise the appropriate error based on the code and type.
178
+
179
+ Args:
180
+ code (str): The error code
181
+ error_type (str): The error type
182
+ message (str): The error message
183
+
184
+ Raises:
185
+ JigsawStackError: If it is a JigsawStack err
186
+ or
187
+ ValidationError: If the error type is validation_error
188
+ or
189
+ MissingRequiredFieldsError: If the error type is missing_required_fields
190
+ or
191
+ MissingApiKeyError: If the error type is missing_api_key
192
+ or
193
+ InvalidApiKeyError: If the error type is invalid_api_key
194
+ or
195
+ ApplicationError: If the error type is application_error
196
+ or
197
+ TypeError: If the error type is not found
198
+ """
199
+ error = ERRORS.get(str(code))
200
+
201
+ # Handle the case where the error might be unknown
202
+ if error is None:
203
+ raise JigsawStackError(
204
+ code=code, message=message, error_type=error_type, suggested_action=""
205
+ )
206
+
207
+ # Raise error from errors list
208
+ error_from_list = error.get(error_type)
209
+
210
+ if error_from_list is not None:
211
+ raise error_from_list(
212
+ code=code,
213
+ message=message,
214
+ error_type=error_type,
215
+ )
216
+ # defaults to JigsawStackError if finally can't find error type
217
+ raise JigsawStackError(
218
+ code=code, message=message, error_type=error_type, suggested_action=""
219
+ )
220
+
221
+
222
+ class NoContentError(Exception):
223
+ """Raised when the response body is empty."""
224
+
225
+ def __init__(self) -> None:
226
+ self.message = """No content was returned from the API.
227
+ Please contact Jigsawstack support."""
228
+ Exception.__init__(self, self.message)
@@ -0,0 +1,116 @@
1
+ from typing import Any, Dict, Generic, List, Union, cast
2
+
3
+ import requests
4
+ from typing_extensions import Literal, TypeVar
5
+
6
+ import jigsawstack
7
+ from jigsawstack.exceptions import NoContentError, raise_for_code_and_type
8
+
9
+ RequestVerb = Literal["get", "post", "put", "patch", "delete"]
10
+
11
+ T = TypeVar("T")
12
+
13
+
14
+ # This class wraps the HTTP request creation logic
15
+ class Request(Generic[T]):
16
+ def __init__(
17
+ self,
18
+ api_url:str,
19
+ api_key:str,
20
+ path: str,
21
+ params: Union[Dict[Any, Any], List[Dict[Any, Any]]],
22
+ verb: RequestVerb
23
+ ):
24
+ self.path = path
25
+ self.params = params
26
+ self.verb = verb
27
+ self.api_url = api_url
28
+ self.api_key = api_key
29
+
30
+ def perform(self) -> Union[T, None]:
31
+ """Is the main function that makes the HTTP request
32
+ to the JigsawStack API. It uses the path, params, and verb attributes
33
+ to make the request.
34
+
35
+ Returns:
36
+ Union[T, None]: A generic type of the Request class or None
37
+
38
+ Raises:
39
+ requests.HTTPError: If the request fails
40
+ """
41
+ resp = self.make_request(url=f"{self.api_url}{self.path}")
42
+
43
+ # delete calls do not return a body
44
+ if resp.text == "" and resp.status_code == 200:
45
+ return None
46
+
47
+ # this is a safety net, if we get here it means the JigsawStack API is having issues
48
+ # and most likely the gateway is returning htmls
49
+ if "application/json" not in resp.headers["content-type"]:
50
+ raise_for_code_and_type(
51
+ code=500,
52
+ message="Failed to parse JigsawStack API response. Please try again.",
53
+ error_type="InternalServerError",
54
+ )
55
+
56
+ # handle error in case there is a statusCode attr present
57
+ # and status != 200 and response is a json.
58
+ if resp.status_code != 200 and resp.json().get("statusCode"):
59
+ error = resp.json()
60
+ raise_for_code_and_type(
61
+ code=error.get("statusCode"),
62
+ message=error.get("message"),
63
+ error_type=error.get("name"),
64
+ )
65
+ return cast(T, resp.json())
66
+
67
+ def perform_with_content(self) -> T:
68
+ """
69
+ Perform an HTTP request and return the response content.
70
+
71
+ Returns:
72
+ T: The content of the response
73
+
74
+ Raises:
75
+ NoContentError: If the response content is `None`.
76
+ """
77
+ resp = self.perform()
78
+ if resp is None:
79
+ raise NoContentError()
80
+ return resp
81
+
82
+ def __get_headers(self) -> Dict[Any, Any]:
83
+ """get_headers returns the HTTP headers that will be
84
+ used for every req.
85
+
86
+ Returns:
87
+ Dict: configured HTTP Headers
88
+ """
89
+ return {
90
+ "Content-Type": "application/json",
91
+ "Accept": "application/json",
92
+ "x-api-key": f"{self.api_key}"
93
+ }
94
+
95
+ def make_request(self, url: str) -> requests.Response:
96
+ """make_request is a helper function that makes the actual
97
+ HTTP request to the JigsawStack API.
98
+
99
+ Args:
100
+ url (str): The URL to make the request to
101
+
102
+ Returns:
103
+ requests.Response: The response object from the request
104
+
105
+ Raises:
106
+ requests.HTTPError: If the request fails
107
+ """
108
+ headers = self.__get_headers()
109
+ params = self.params
110
+ verb = self.verb
111
+
112
+ print("ABOUT TO MAKE REQUEST WITH HEADERS",headers)
113
+ try:
114
+ return requests.request(verb, url, json=params, headers=headers,)
115
+ except requests.HTTPError as e:
116
+ raise e
@@ -0,0 +1,62 @@
1
+ Metadata-Version: 2.1
2
+ Name: jigsawstack
3
+ Version: 0.1
4
+ Summary: JigsawStack Python SDK
5
+ Home-page: https://github.com/jigsawstack/jigsawstack-py
6
+ Author: Narcisse
7
+ Author-email: hello@jigsawstack.com
8
+ Keywords: AI,AI Tooling
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Natural Language :: English
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3.7
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Requires-Python: >=3.7
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: requests>=2.31.0
22
+ Requires-Dist: typing_extensions
23
+
24
+ # JigsawStack Python SDK
25
+
26
+ ## Installation
27
+
28
+ To install JigsawStack Python SDK, simply execute the following command in a terminal:
29
+
30
+ ```
31
+ pip install jigsawstack
32
+ ```
33
+
34
+ ## Setup
35
+
36
+ First, you need to get an API key, which is available in the [JigsawStack Dashboard](https://jigsawstack.com).
37
+
38
+ ```py
39
+ from jigsawstack from JigsawStack
40
+
41
+ import os
42
+
43
+ ai = JigsawStack(api_key="your-api-key")
44
+ ```
45
+
46
+ ## Example
47
+
48
+ ```py
49
+ import os
50
+ from jigsawstack from JigsawStack
51
+
52
+
53
+ ai = JigsawStack(api_key="your-api-key")
54
+
55
+ params = {
56
+ "url": "https://rogilvkqloanxtvjfrkm.supabase.co/storage/v1/object/public/demo/Collabo%201080x842.jpg?t=2024-03-22T09%3A22%3A48.442Z"
57
+ }
58
+
59
+ result = ai.vision.vocr(params)
60
+
61
+ print(result)
62
+ ```
@@ -0,0 +1,16 @@
1
+ README.md
2
+ setup.py
3
+ jigsawstack/__init__.py
4
+ jigsawstack/_client.py
5
+ jigsawstack/_config.py
6
+ jigsawstack/exceptions.py
7
+ jigsawstack/request.py
8
+ jigsawstack.egg-info/PKG-INFO
9
+ jigsawstack.egg-info/SOURCES.txt
10
+ jigsawstack.egg-info/dependency_links.txt
11
+ jigsawstack.egg-info/not-zip-safe
12
+ jigsawstack.egg-info/requires.txt
13
+ jigsawstack.egg-info/top_level.txt
14
+ tests/test_search.py
15
+ tests/test_sentiment.py
16
+ tests/test_web.py
@@ -0,0 +1,2 @@
1
+ requests>=2.31.0
2
+ typing_extensions
@@ -0,0 +1 @@
1
+ jigsawstack
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env python
2
+
3
+ from setuptools import find_packages, setup
4
+
5
+
6
+ install_requires = open("requirements.txt").readlines()
7
+
8
+ setup(
9
+ name="jigsawstack",
10
+ version="0.1",
11
+ description="JigsawStack Python SDK",
12
+ long_description=open("README.md", encoding="utf8").read(),
13
+ long_description_content_type="text/markdown",
14
+ author="Narcisse",
15
+ author_email="hello@jigsawstack.com",
16
+ url="https://github.com/jigsawstack/jigsawstack-py",
17
+ packages=find_packages(include=["jigsawstack"]),
18
+ install_requires=install_requires,
19
+ zip_safe=False,
20
+ python_requires=">=3.7",
21
+ keywords=["AI", "AI Tooling"],
22
+ setup_requires=['pytest-runner'],
23
+ tests_require=['pytest'],
24
+ test_suite='tests',
25
+ classifiers=[
26
+ "Development Status :: 4 - Beta",
27
+ "Intended Audience :: Developers",
28
+ "License :: OSI Approved :: MIT License",
29
+ "Natural Language :: English",
30
+ "Operating System :: OS Independent",
31
+ "Programming Language :: Python :: 3.7",
32
+ "Programming Language :: Python :: 3.8",
33
+ "Programming Language :: Python :: 3.9",
34
+ "Programming Language :: Python :: 3.10",
35
+ "Programming Language :: Python :: 3.11",
36
+ ],
37
+ )
@@ -0,0 +1,32 @@
1
+ from unittest.mock import MagicMock
2
+ import unittest
3
+ from jigsawstack.exceptions import JigsawStackError
4
+ import jigsawstack
5
+ import pytest
6
+ # flake8: noq
7
+
8
+ jigsaw = jigsawstack.JigsawStack()
9
+
10
+
11
+
12
+ class TestSearchAPI(unittest.TestCase):
13
+
14
+ def test_search_suggestion_response_success(self) -> None:
15
+ params = {
16
+ "query": "Time Square New Yor"
17
+ }
18
+ try:
19
+ result = jigsaw.search.suggestion(params)
20
+ assert result["success"] == True
21
+ except JigsawStackError as e:
22
+ assert e.message == "Failed to parse API response. Please try again."
23
+
24
+ def test_ai_search_response_success(self) -> None:
25
+ params = {
26
+ "query": "Time Square New Yor"
27
+ }
28
+ try:
29
+ result = jigsaw.search.ai_search(params)
30
+ assert result["success"] == True
31
+ except JigsawStackError as e:
32
+ assert e.message == "Failed to parse API response. Please try again."
@@ -0,0 +1,21 @@
1
+ from unittest.mock import MagicMock
2
+ import unittest
3
+ from jigsawstack.exceptions import JigsawStackError
4
+ import jigsawstack
5
+
6
+ import pytest
7
+ # flake8: noqa
8
+
9
+ client = jigsawstack.JigsawStack()
10
+
11
+ @pytest.mark.skip(reason="Skipping TestWebAPI class for now")
12
+ class TestSentimentAPI(unittest.TestCase):
13
+ def test_sentiment_response_success(self) -> None:
14
+ params = {
15
+ "text": "I am so excited"
16
+ }
17
+ try:
18
+ result = client.sentiment.analyze(params)
19
+ assert result["success"] == True
20
+ except JigsawStackError as e:
21
+ assert e.message == "Failed to parse API response. Please try again."
@@ -0,0 +1,49 @@
1
+ from unittest.mock import MagicMock
2
+ import unittest
3
+
4
+ from jigsawstack.exceptions import JigsawStackError
5
+
6
+ import jigsawstack
7
+ import jigsawstack.sentiment
8
+ import jigsawstack.sentiment._sentiment
9
+ import jigsawstack.translate
10
+ import jigsawstack.translate._translate
11
+ import jigsawstack.web
12
+ import jigsawstack
13
+ import pytest
14
+ # flake8: noqa
15
+
16
+
17
+ @pytest.mark.skip(reason="Skipping TestWebAPI class for now")
18
+ class TestWebAPI(unittest.TestCase):
19
+ def test_ai_scrape_success_response(self) -> None:
20
+ params = {
21
+ "url": "https://supabase.com/pricing",
22
+ "element_prompts": ["Plan title", "Plan price"],
23
+ }
24
+ try:
25
+ result = jigsawstack.Web.ai_scrape(params)
26
+ assert result["success"] == True
27
+ except JigsawStackError as e:
28
+ assert e.message == "Failed to parse API response. Please try again."
29
+
30
+ def test_scrape_success_response(self) -> None:
31
+ params = {
32
+ "url": "https://supabase.com/pricing",
33
+ }
34
+ try:
35
+ result = jigsawstack.Web.scrape(params)
36
+ assert result["success"] == True
37
+ except JigsawStackError as e:
38
+ assert e.message == "Failed to parse API response. Please try again."
39
+
40
+ def test_dns_success_response(self) -> None:
41
+
42
+ params = {
43
+ "url": "https://supabase.com/pricing",
44
+ }
45
+ try:
46
+ result = jigsawstack.Web.dns(params)
47
+ assert result["success"] == True
48
+ except JigsawStackError as e:
49
+ assert e.message == "Failed to parse API response. Please try again."