11import json
2+ from typing import Any , Dict , Iterator , Optional , Union , TYPE_CHECKING
23
3- from pprint import pformat
44from collections import UserDict
55
6+ import requests
7+
68from .textui import prettify_json
7- from .exceptions import HTTPError
9+
10+ if TYPE_CHECKING :
11+ from .core import Client
812
913
10- class SerpResults (UserDict ):
14+ class SerpResults (UserDict [ str , Any ] ):
1115 """A dictionary-like object that represents the results of a SerpApi request.
1216
1317 .. code-block:: python
@@ -21,68 +25,71 @@ class SerpResults(UserDict):
2125 It can be used like a dictionary, but also has some additional methods.
2226 """
2327
24- def __init__ (self , data , * , client ) :
28+ def __init__ (self , data : Dict [ str , Any ], * , client : Optional [ "Client" ]) -> None :
2529 super ().__init__ (data )
2630 self .client = client
2731
28- def __getstate__ (self ):
32+ def __getstate__ (self ) -> Dict [ str , Any ] :
2933 return self .data
3034
31- def __setstate__ (self , state ) :
35+ def __setstate__ (self , state : Dict [ str , Any ]) -> None :
3236 self .data = state
3337
34- def __repr__ (self ):
38+ def __repr__ (self ) -> str :
3539 """The visual representation of the data, which is pretty printed, for
3640 ease of use.
3741 """
3842
3943 return prettify_json (json .dumps (self .data , indent = 4 ))
4044
41- def as_dict (self ):
45+ def as_dict (self ) -> Dict [ str , Any ] :
4246 """Returns the data as a standard Python dictionary.
4347 This can be useful when using ``json.dumps(search), for example."""
4448
4549 return self .data .copy ()
4650
4751 @property
48- def next_page_url (self ):
52+ def next_page_url (self ) -> Optional [ str ] :
4953 """The URL of the next page of results, if any."""
5054
51- serpapi_pagination = self .data .get ("serpapi_pagination" )
55+ serpapi_pagination : Optional [ dict [ str , Any ]] = self .data .get ("serpapi_pagination" )
5256
5357 if serpapi_pagination :
54- return serpapi_pagination .get ("next" )
58+ next_url = serpapi_pagination .get ("next" )
59+ return next_url if isinstance (next_url , str ) else None
60+ return None
5561
56- def next_page (self ):
62+ def next_page (self ) -> Optional [ Union [ "SerpResults" , str ]] :
5763 """Return the next page of results, if any."""
5864
59- if self .next_page_url :
65+ if self .next_page_url and self . client is not None :
6066 # Include support for the API key, as it is not included in the next page URL.
6167 params = {"api_key" : self .client .api_key }
6268
6369 r = self .client .request ("GET" , path = self .next_page_url , params = params )
6470 return SerpResults .from_http_response (r , client = self .client )
6571
66- def yield_pages (self , max_pages = 1_000 ):
72+ return None
73+
74+ def yield_pages (self , max_pages : int = 1_000 ) -> Iterator [Union ["SerpResults" , str ]]:
6775 """A generator that ``yield`` s the next ``n`` pages of search results, if any.
6876
6977 :param max_pages: limit the number of pages yielded to ``n``.
7078 """
7179
7280 current_page_count = 0
73-
74- current_page = self
81+ current_page : Union ["SerpResults" , str , None ] = self
7582 while current_page and current_page_count < max_pages :
7683 yield current_page
7784 current_page_count += 1
78- if current_page .next_page_url :
85+ if isinstance ( current_page , SerpResults ) and current_page .next_page_url :
7986 current_page = current_page .next_page ()
8087 else :
8188 break
8289
8390
8491 @classmethod
85- def from_http_response (cls , r , * , client = None ):
92+ def from_http_response (cls , r : requests . Response , * , client : Optional [ "Client" ] = None ) -> Union [ "SerpResults" , str ] :
8693 """Construct a SerpResults object from an HTTP response.
8794
8895 :param assert_200: if ``True`` (default), raise an exception if the status code is not 200.
@@ -93,9 +100,9 @@ def from_http_response(cls, r, *, client=None):
93100 """
94101
95102 try :
96- cls = cls (r .json (), client = client )
103+ inst = cls (r .json (), client = client )
97104
98- return cls
105+ return inst
99106 except ValueError :
100107 # If the response is not JSON, return the raw text.
101108 return r .text
0 commit comments