Skip to content

Commit acb5d7a

Browse files
authored
Merge pull request #3 from ScrapingAnt/feature/issue1-add-exceptions-handling
feature/issue1-add-exceptions-handling: added eroors, tests, imporoved README
2 parents b66c34b + fb1e800 commit acb5d7a

File tree

7 files changed

+100
-22
lines changed

7 files changed

+100
-22
lines changed

README.md

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ Python applications. It provides useful features like parameters encoding to im
55
<!-- toc -->
66

77
- [Quick Start](#quick-start)
8-
- [API key](#api-key)
8+
- [API token](#api-token)
99
- [API Reference](#api-reference)
10+
- [Exceptions](#exceptions)
1011
- [Examples](#examples)
1112

1213
<!-- tocstop -->
@@ -21,27 +22,25 @@ result = client.general_request('https://example.com')
2122
print(result.content)
2223
```
2324

24-
## API key
25-
In order to get API key you'll need to register at [ScrapingAnt Service](https://app.scrapingant.com)
25+
## API token
26+
In order to get API token you'll need to register at [ScrapingAnt Service](https://app.scrapingant.com)
2627

2728
## API Reference
2829
All public classes, methods and their parameters can be inspected in this API reference.
2930

3031
<a name="ScrapingAntClient"></a>
3132

32-
#### [](#ScrapingAntClient) `ScrapingAntClient(token)`
33+
#### [](#ScrapingAntClient) ScrapingAntClient(token)
3334

35+
Main class of this library.
3436

35-
| Param | Type | Default |
36-
| --- | --- | --- |
37-
| token | <code>string</code> | |
38-
37+
| Param | Type |
38+
| --- | --- |
39+
| token | <code>string</code> |
3940

4041
* * *
4142

42-
<a name="ScrapingAntClient+scrape"></a>
43-
44-
### [](#ScrapingAntClient+scrape) `ScrapingAntClient.general_request(url, cookies, js_snippet, proxy_country, return_text)` ⇒ Response
43+
#### [](#ScrapingAntClient+general_request) `ScrapingAntClient.general_request(url, cookies, js_snippet, proxy_country, return_text)` ⇒ Response
4544

4645
https://docs.scrapingant.com/request-response-format#available-parameters
4746

@@ -57,7 +56,7 @@ https://docs.scrapingant.com/request-response-format#available-parameters
5756

5857
* * *
5958

60-
### [](#Cookie) Cookie
59+
#### [](#Cookie) Cookie
6160
Class defining cookie. Curently supports only name and value
6261

6362
| Param | Type |
@@ -67,25 +66,29 @@ Class defining cookie. Curently supports only name and value
6766

6867
* * *
6968

70-
### [](#ProxyCountry) ProxyCountry
69+
#### [](#ProxyCountry) ProxyCountry
7170

7271
Enum containing all available proxy countries
7372

7473
* * *
7574

76-
### [](#Response) Response
75+
#### [](#Response) Response
7776
Class defining cookie. Curently supports only name and value
7877

7978
| Param | Type |
8079
| --- | --- |
8180
| content | <code>string</code> |
8281
| cookies | <code>List[Cookie]</code> |
8382

84-
* * *
83+
## [](#exceptions) Exceptions
8584

86-
### [](#ScrapingantClientException) ScrapingantClientException
85+
`ScrapingantClientException` is base Exception class, used for all errors.
8786

88-
`ScrapingantClientException` is base Exception class, used for all errors.
87+
| Exception | Reason |
88+
| --- | --- |
89+
| ScrapingantInvalidTokenException | The API token is wrong or you have exceeded the API calls request limit
90+
| ScrapingantInvalidInputException | Invalid value provided. Please, look into error message for more info |
91+
| ScrapingantInternalException | Something went wrong with the server side code. Try again later or contact ScrapingAnt support |
8992

9093
* * *
9194

scrapingant_client/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
from scrapingant_client.client import ScrapingAntClient
22
from scrapingant_client.constants import ProxyCountry
33
from scrapingant_client.cookie import Cookie
4-
from scrapingant_client.errors import ScrapingantClientException
4+
from scrapingant_client.errors import (
5+
ScrapingantClientException,
6+
ScrapingantInvalidTokenException,
7+
ScrapingantInvalidInputException,
8+
ScrapingantInternalException,
9+
)
510
from scrapingant_client.response import Response
611

712
__all__ = [
813
'ScrapingAntClient',
914
'ProxyCountry',
1015
'Cookie',
1116
'ScrapingantClientException',
17+
'ScrapingantInvalidTokenException',
18+
'ScrapingantInvalidInputException',
19+
'ScrapingantInternalException',
1220
'Response',
1321
]

scrapingant_client/client.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@
44

55
import requests
66

7-
from scrapingant_client.constants import ProxyCountry
7+
from scrapingant_client.constants import ProxyCountry, SCRAPINGANT_API_BASE_URL
88
from scrapingant_client.cookie import Cookie, cookies_list_to_string, cookies_list_from_string
9+
from scrapingant_client.errors import (
10+
ScrapingantInvalidTokenException,
11+
ScrapingantInvalidInputException,
12+
ScrapingantInternalException,
13+
)
914
from scrapingant_client.response import Response
1015
from scrapingant_client.utils import base64_encode_string
1116

1217

1318
class ScrapingAntClient:
1419
def __init__(self, token: str):
1520
self.token = token
16-
self.scrapingant_api_base_url = 'https://api.scrapingant.com/v1'
1721
self.requests_session = requests.Session()
1822
user_agent = f'ScrapingAntClient ({sys.platform}; Python/{platform.python_version()});'
1923
self.requests_session.headers.update({
@@ -41,9 +45,15 @@ def general_request(
4145
request_data['return_text'] = True
4246

4347
response = self.requests_session.post(
44-
self.scrapingant_api_base_url + '/general',
48+
SCRAPINGANT_API_BASE_URL + '/general',
4549
json=request_data,
4650
)
51+
if response.status_code == 403:
52+
raise ScrapingantInvalidTokenException()
53+
elif response.status_code == 422:
54+
raise ScrapingantInvalidInputException(response.text)
55+
elif response.status_code == 500:
56+
raise ScrapingantInternalException()
4757
json_response = response.json()
4858
content = json_response['content']
4959
cookies_string = json_response['cookies']

scrapingant_client/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from enum import Enum
22

3+
SCRAPINGANT_API_BASE_URL = 'https://api.scrapingant.com/v1'
4+
35

46
class ProxyCountry(str, Enum):
57
brasilia = 'br'

scrapingant_client/errors.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
11
class ScrapingantClientException(Exception):
22
"""Base class for errors specific to the ScrapingAnt Client."""
33
pass
4+
5+
6+
class ScrapingantInvalidTokenException(ScrapingantClientException):
7+
def __init__(self):
8+
message = 'API token is wrong or you have exceeded the API calls request limit'
9+
super().__init__(message)
10+
11+
12+
class ScrapingantInvalidInputException(ScrapingantClientException):
13+
pass
14+
15+
16+
class ScrapingantInternalException(ScrapingantClientException):
17+
def __init__(self):
18+
message = 'Something went wrong with the server side. Please try later or contact support'
19+
super().__init__(message)

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="scrapingant-client",
8-
version="0.1.0",
8+
version="0.2.0",
99
author="andrii.kovalenko",
1010
author_email="[email protected]",
1111
license='Apache-2.0',
@@ -32,6 +32,7 @@
3232
'dev': [
3333
'pytest>=6,<7',
3434
'flake8>=3,<4',
35+
'responses>=0,<1'
3536
]
3637
}
3738
)

tests/test_exceptions.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import pytest
2+
import responses
3+
4+
from scrapingant_client import (
5+
ScrapingAntClient,
6+
ScrapingantInvalidTokenException,
7+
ScrapingantInvalidInputException,
8+
ScrapingantInternalException,
9+
)
10+
from scrapingant_client.constants import SCRAPINGANT_API_BASE_URL
11+
12+
13+
@responses.activate
14+
def test_invalid_token():
15+
responses.add(responses.POST, SCRAPINGANT_API_BASE_URL + '/general',
16+
json={'detail': 'wrong token'}, status=403)
17+
client = ScrapingAntClient(token='invalid_token')
18+
with pytest.raises(ScrapingantInvalidTokenException):
19+
client.general_request('example.com')
20+
21+
22+
@responses.activate
23+
def test_invalid_input():
24+
responses.add(responses.POST, SCRAPINGANT_API_BASE_URL + '/general',
25+
json={'detail': 'wrong url'}, status=422)
26+
client = ScrapingAntClient(token='some_token')
27+
with pytest.raises(ScrapingantInvalidInputException) as e:
28+
client.general_request('bad_url')
29+
assert '{"detail": "wrong url"}' in str(e)
30+
31+
32+
@responses.activate
33+
def test_internal_server_error():
34+
responses.add(responses.POST, SCRAPINGANT_API_BASE_URL + '/general',
35+
json={}, status=500)
36+
client = ScrapingAntClient(token='some_token')
37+
with pytest.raises(ScrapingantInternalException):
38+
client.general_request('bad_url')

0 commit comments

Comments
 (0)