| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -50,6 +50,29 @@ Let's print the title of the first result, but in a more Pythonic way: | |||
| 50 | 50 | ||
| 51 | 51 | The [SerpApi.com API Documentation](https://serpapi.com/search-api) contains a list of all the possible parameters that can be passed to the API. | |
| 52 | 52 | ||
| 53 | + ### Error handling | ||
| 54 | + | ||
| 55 | + Unsuccessful requests raise `serpapi.HTTPError` exception. The returned status code will reflect the sort of error that occurred, please refer to [Status and Error Codes Documentation](https://serpapi.com/api-status-and-error-codes) for more details. | ||
| 56 | + | ||
| 57 | + ```python | ||
| 58 | + import serpapi | ||
| 59 | + | ||
| 60 | + client = serpapi.Client(api_key=os.getenv("API_KEY")) | ||
| 61 | + | ||
| 62 | + try: | ||
| 63 | + results = client.search({ | ||
| 64 | + 'engine': 'google', | ||
| 65 | + 'q': 'coffee', | ||
| 66 | + }) | ||
| 67 | + except serpapi.HTTPError as e: | ||
| 68 | + if e.status_code == 401: # Invalid API key | ||
| 69 | + print(e.error) # "Invalid API key. Your API key should be here: https://serpapi.com/manage-api-key" | ||
| 70 | + elif e.status_code == 400: # Missing required parameter | ||
| 71 | + pass | ||
| 72 | + elif e.status_code == 429: # Exceeds the hourly throughput limit OR account run out of searches | ||
| 73 | + pass | ||
| 74 | + ``` | ||
| 75 | + | ||
| 53 | 76 | ## Documentation | |
| 54 | 77 | ||
| 55 | 78 | Documentation is [available on Read the Docs](https://serpapi-python.readthedocs.io/en/latest/). | |
@@ -339,7 +362,6 @@ results = client.search({ | |||
| 339 | 362 | ``` | |
| 340 | 363 | - API Documentation: [serpapi.com/images-results](https://serpapi.com/images-results) | |
| 341 | 364 | ||
| 342 | - | ||
| 343 | 365 | ## License | |
| 344 | 366 | ||
| 345 | 367 | MIT License. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,7 +22,21 @@ class SearchIDNotProvided(ValueError, SerpApiError): | |||
| 22 | 22 | class HTTPError(requests.exceptions.HTTPError, SerpApiError): | |
| 23 | 23 | """HTTP Error.""" | |
| 24 | 24 | ||
| 25 | - pass | ||
| 25 | + def __init__(self, original_exception): | ||
| 26 | + if (isinstance(original_exception, requests.exceptions.HTTPError)): | ||
| 27 | + http_error_exception: requests.exceptions.HTTPError = original_exception | ||
| 28 | + | ||
| 29 | + self.status_code = http_error_exception.response.status_code | ||
| 30 | + try: | ||
| 31 | + self.error = http_error_exception.response.json().get("error", None) | ||
| 32 | + except requests.exceptions.JSONDecodeError: | ||
| 33 | + self.error = None | ||
| 34 | + else: | ||
| 35 | + self.status_code = -1 | ||
| 36 | + self.error = None | ||
| 37 | + | ||
| 38 | + super().__init__(*original_exception.args, response=getattr(original_exception, 'response', None), request=getattr(original_exception, 'request', None)) | ||
| 39 | + | ||
| 26 | 40 | ||
| 27 | 41 | ||
| 28 | 42 | class HTTPConnectionError(HTTPError, requests.exceptions.ConnectionError, SerpApiError): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,17 @@ | |||
| 1 | + from unittest.mock import Mock | ||
| 2 | + import requests | ||
| 3 | + import serpapi | ||
| 4 | + | ||
| 5 | + | ||
| 6 | + def test_http_error(): | ||
| 7 | + """Ensure that an HTTPError has the correct status code and error.""" | ||
| 8 | + mock_response = Mock() | ||
| 9 | + mock_response.status_code = 401 | ||
| 10 | + mock_response.json.return_value = { "error": "Invalid API key" } | ||
| 11 | + | ||
| 12 | + requests_error = requests.exceptions.HTTPError(response=mock_response, request=Mock()) | ||
| 13 | + http_error = serpapi.HTTPError(requests_error) | ||
| 14 | + | ||
| 15 | + assert http_error.status_code == 401 | ||
| 16 | + assert http_error.error == "Invalid API key" | ||
| 17 | + assert http_error.response == mock_response | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,8 +26,10 @@ def test_account_without_credentials(): | |||
| 26 | 26 | ||
| 27 | 27 | def test_account_with_bad_credentials(invalid_key_client): | |
| 28 | 28 | """Ensure that an HTTPError is raised when account is accessed with invalid API Credentials.""" | |
| 29 | - with pytest.raises(serpapi.HTTPError): | ||
| 29 | + with pytest.raises(serpapi.HTTPError) as exc_info: | ||
| 30 | 30 | invalid_key_client.account() | |
| 31 | + | ||
| 32 | + assert exc_info.value.response.status_code == 401 | ||
| 31 | 33 | ||
| 32 | 34 | ||
| 33 | 35 | def test_account_with_credentials(client): | |
@@ -38,6 +40,14 @@ def test_account_with_credentials(client): | |||
| 38 | 40 | assert isinstance(account, dict) | |
| 39 | 41 | ||
| 40 | 42 | ||
| 43 | + def test_search_with_missing_params(client): | ||
| 44 | + with pytest.raises(serpapi.HTTPError) as exc_info: | ||
| 45 | + client.search({ "q": "" }) | ||
| 46 | + | ||
| 47 | + assert exc_info.value.status_code == 400 | ||
| 48 | + assert "Missing query `q` parameter" in exc_info.value.error | ||
| 49 | + | ||
| 50 | + | ||
| 41 | 51 | def test_coffee_search(coffee_search): | |
| 42 | 52 | assert isinstance(coffee_search, serpapi.SerpResults) | |
| 43 | 53 | assert hasattr(coffee_search, "__getitem__") | |
| Back | FazBrowse Home | New Git URL |
0 commit comments