@@ -40,9 +40,14 @@ class Keepa:
4040 server has not issued a response for timeout seconds. Setting this to
4141 0.0 disables the timeout, but will cause any request to hang
4242 indefiantly should keepa.com be down
43- logging_level: string , default: "DEBUG"
43+ logging_level: str , default: "DEBUG"
4444 Logging level to use. Default is "DEBUG". Other options are "INFO",
4545 "WARNING", "ERROR", and "CRITICAL".
46+ check_key : bool, default: True
47+ Check the keepa key on initialization and update the number of
48+ available tokens. This is a free check and does not cost any tokens,
49+ but does slow down the time to initialize. Disable this to speed up
50+ init at the risk of using an invalid key when querying for a product.
4651
4752 Examples
4853 --------
@@ -81,7 +86,13 @@ class Keepa:
8186 status : Status
8287 _timeout : float
8388
84- def __init__ (self , accesskey : str , timeout : float = 10.0 , logging_level : str = "DEBUG" ) -> None :
89+ def __init__ (
90+ self ,
91+ accesskey : str ,
92+ timeout : float = 10.0 ,
93+ logging_level : str = "DEBUG" ,
94+ check_key : bool = False ,
95+ ) -> None :
8596 """Initialize server connection."""
8697 self .accesskey = accesskey
8798 self .tokens_left = 0
@@ -93,9 +104,11 @@ def __init__(self, accesskey: str, timeout: float = 10.0, logging_level: str = "
93104 raise TypeError ("logging_level must be one of: " + ", " .join (levels ))
94105 log .setLevel (logging_level )
95106
96- # Don't check available tokens on init
107+ # Check available tokens on init
97108 log .info ("Using key ending in %s" , accesskey [- 6 :])
98109 self .status = Status ()
110+ if check_key :
111+ self .update_status ()
99112
100113 @property
101114 def time_to_refill (self ) -> float :
@@ -114,6 +127,20 @@ def time_to_refill(self) -> float:
114127 0.0
115128
116129 """
130+ if (
131+ self .status .refillRate is None
132+ or self .status .refillIn is None
133+ or self .status .timestamp is None
134+ ):
135+ self .update_status ()
136+
137+ if (
138+ self .status .refillRate is None
139+ or self .status .refillIn is None
140+ or self .status .timestamp is None
141+ ):
142+ raise RuntimeError ("Failed to update status" )
143+
117144 # Get current timestamp in milliseconds from UNIX epoch
118145 now = int (time .time () * 1000 )
119146 time_at_refill = self .status .timestamp + self .status .refillIn
@@ -130,11 +157,10 @@ def time_to_refill(self) -> float:
130157 # Return value in seconds
131158 return time_to_refill / 1000.0
132159
133- def update_status (self ) -> dict [ str , Any ] :
160+ def update_status (self ) -> None :
134161 """Update available tokens."""
135- status = self ._request ("token" , {"key" : self .accesskey }, wait = False )
136- self .status = status
137- return status
162+ # number of available tokens is always returned
163+ self ._request ("token" , {"key" : self .accesskey }, wait = False )
138164
139165 def wait_for_tokens (self ) -> None :
140166 """Check if there are any remaining tokens and waits if none are available."""
@@ -143,7 +169,7 @@ def wait_for_tokens(self) -> None:
143169 # Wait if no tokens available
144170 if self .tokens_left <= 0 :
145171 tdelay = self .time_to_refill
146- log .warning ("Waiting %.0f seconds for additional tokens" % tdelay )
172+ log .warning ("Waiting %.0f seconds for additional tokens" , tdelay )
147173 time .sleep (tdelay )
148174 self .update_status ()
149175
@@ -632,6 +658,11 @@ def query(
632658 if offers > 100 or offers < 20 :
633659 raise ValueError ('Parameter "offers" must be between 20 and 100' )
634660
661+ if self .status .refillRate is None or self .status .refillIn is None :
662+ self .update_status ()
663+ if self .status .refillRate is None or self .status .refillIn is None :
664+ raise RuntimeError ("Failed to update status" )
665+
635666 # Report time to completion
636667 if self .status .refillRate is not None :
637668 tcomplete = (
@@ -797,7 +828,7 @@ def _product_query(self, items, product_code_is_asin=True, **kwargs):
797828 to_datetime = kwargs .pop ("to_datetime" , True )
798829
799830 # Query and replace csv with parsed data if history enabled
800- wait = kwargs .get ("wait" )
831+ wait = bool ( kwargs .get ("wait" ) )
801832 kwargs .pop ("wait" , None )
802833 raw_response = kwargs .pop ("raw" , False )
803834 response = self ._request ("product" , kwargs , wait = wait , raw_response = raw_response )
@@ -956,7 +987,7 @@ def best_sellers_query(
956987
957988 def search_for_categories (
958989 self , searchterm : str , domain : str | Domain = "US" , wait : bool = True
959- ) -> list :
990+ ) -> dict [ str , Any ] :
960991 """
961992 Search for categories from Amazon.
962993
0 commit comments