@@ -32,15 +32,17 @@ class InvalidInputError(OpenCageGeocodeError):
3232 """
3333 There was a problem with the input you provided.
3434
35- :var bad_value: The value that caused the problem
35+ :var message: Error message describing the bad input.
36+ :var bad_value: The value that caused the problem.
3637 """
3738
38- def __init__ (self , bad_value ):
39+ def __init__ (self , message , bad_value = None ):
3940 super ().__init__ ()
41+ self .message = message
4042 self .bad_value = bad_value
4143
4244 def __unicode__ (self ):
43- return "Input must be a unicode string, not " + repr ( self .bad_value )[: 100 ]
45+ return self .message
4446
4547 __str__ = __unicode__
4648
@@ -135,13 +137,19 @@ class OpenCageGeocode:
135137
136138 def __init__ (
137139 self ,
138- key ,
140+ key = None ,
139141 protocol = 'https' ,
140142 domain = DEFAULT_DOMAIN ,
141143 sslcontext = None ,
142144 user_agent_comment = None ):
143145 """Constructor."""
144- self .key = key
146+ self .key = key if key is not None else os .environ .get ('OPENCAGE_API_KEY' )
147+
148+ if self .key is None :
149+ raise ValueError (
150+ "API key not provided. "
151+ "Either pass a 'key' parameter or set the OPENCAGE_API_KEY environment variable."
152+ )
145153
146154 if protocol and protocol not in ('http' , 'https' ):
147155 protocol = 'https'
@@ -243,7 +251,11 @@ def reverse_geocode(self, lat, lng, **kwargs):
243251 :raises RateLimitExceededError: if you have exceeded the number of queries you can make.
244252 : Exception says when you can try again
245253 :raises UnknownError: if something goes wrong with the OpenCage API
254+ :raises InvalidInputError: if the latitude or longitude is out of bounds
246255 """
256+
257+ self ._validate_lat_lng (lat , lng )
258+
247259 return self .geocode (_query_for_reverse_geocoding (lat , lng ), ** kwargs )
248260
249261 async def reverse_geocode_async (self , lat , lng , ** kwargs ):
@@ -258,7 +270,11 @@ async def reverse_geocode_async(self, lat, lng, **kwargs):
258270 :rtype: dict
259271 :raises RateLimitExceededError: if exceeded number of queries you can make. You can try again
260272 :raises UnknownError: if something goes wrong with the OpenCage API
273+ :raises InvalidInputError: if the latitude or longitude is out of bounds
261274 """
275+
276+ self ._validate_lat_lng (lat , lng )
277+
262278 return await self .geocode_async (_query_for_reverse_geocoding (lat , lng ), ** kwargs )
263279
264280 @backoff .on_exception (
@@ -340,12 +356,33 @@ async def _opencage_async_request(self, params):
340356
341357 def _parse_request (self , query , params ):
342358 if not isinstance (query , str ):
343- raise InvalidInputError (bad_value = query )
359+ error_message = "Input must be a unicode string, not " + repr (query )[:100 ]
360+ raise InvalidInputError (error_message , bad_value = query )
344361
345362 data = {'q' : query , 'key' : self .key }
346363 data .update (params ) # Add user parameters
347364 return data
348365
366+ def _validate_lat_lng (self , lat , lng ):
367+ """
368+ Validate latitude and longitude values.
369+
370+ Raises InvalidInputError if the values are out of bounds.
371+ """
372+ try :
373+ lat_float = float (lat )
374+ if not - 90 <= lat_float <= 90 :
375+ raise InvalidInputError (f"Latitude must be a number between -90 and 90, not { lat } " , bad_value = lat )
376+ except ValueError :
377+ raise InvalidInputError (f"Latitude must be a number between -90 and 90, not { lat } " , bad_value = lat )
378+
379+ try :
380+ lng_float = float (lng )
381+ if not - 180 <= lng_float <= 180 :
382+ raise InvalidInputError (f"Longitude must be a number between -180 and 180, not { lng } " , bad_value = lng )
383+ except ValueError :
384+ raise InvalidInputError (f"Longitude must be a number between -180 and 180, not { lng } " , bad_value = lng )
385+
349386
350387def _query_for_reverse_geocoding (lat , lng ):
351388 """
0 commit comments