I am trying to call GoogleV3 geolocator like this:
geolocator = GoogleV3(proxies={"http": "http://user:password@ip:port"})
address, (latitude, longitude) = geolocator.geocode('address to geocode')
and it raises:
AttributeError: OpenerDirector instance has no __call__ method
What am I doing wrong? How to fix it?
It is not possible in current implementation of GoogleV3 to pass user and password variables directly to urllib2.opener (GoogleV3 uses urllib2 behind the scenes).
Here is example how urllib2.opener should be called:
proxy_handler = urllib2.ProxyHandler({'http': 'http://www.example.com:3128/'})
proxy_auth_handler = urllib2.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
opener = urllib2.build_opener(proxy_handler, proxy_auth_handler)
# This time, rather than install the OpenerDirector, we use it directly:
opener.open('http://www.example.com/login.html')
Sadly, but current GoogleV3 implementation does not use urllib2.ProxyBasicAuthHandler .
So, you need to extend it by modifying source: https://github.com/geopy/geopy/blob/master/geopy/geocoders/base.py On the top add:
from urlparse import urlparse
then find 'if self.proxies is None:' code and replace it with:
if self.proxies is None:
self.urlopen = urllib_urlopen
else:
params = urlparse(proxies[1])
host = params.get('hostname')
username = params.get('username')
password = params.get('password')
if host and username and password:
proxy_auth_handler = urllib2.ProxyBasicAuthHandler()
proxy_auth_handler.add_password(None, host, username, password)
self.urlopen = build_opener(
ProxyHandler(self.proxies, proxy_auth_handler),
)