GeoIP in Google App Engine

It is surprising to me that Google does not offer any service or method in Google App Engine to get the geographic location from a IP. This is something they have in tons of products, and offering this will be something really simple to do for them. I don’t see why they are not offering this to GAE developers (they offer a solution in the client side, if you want to use their javascript, google.loader.ClientLocation)

Fortunately, this problem has two easy solutions.

Solution 1: do a request to another server

You can do an HTTP  request to http://geoip.wtanaka.com/ and this server will return the country code:

For example, to know the country of the ip 72.14.235.121 you will only have to do a request to  http://geoip.wtanaka.com/cc/72.14.235.121

If you want to know how to do this kind of requests, take a look to  http://code.google.com/p/geo-ip-location/wiki/GoogleAppEngine

Solution 2: implement it in your own server

This is the solution I like the most. You just download the latest version of  GeoIP.dat and you use it with the  pygeoip.py library.

Using it is as easy as:

def getCountryByIP (remote_addr):
  GEOIP = pygeoip.Database('GeoIP.dat')
  info = GEOIP.lookup(remote_addr)
  return info.country

Please note that using the function I defined before will not be the best practice for this library. This library has been though to  load everything into memory, so they speed-up lookups. Each time pygeoip.Database is called, the GeoIP.dat file is loaded into memory, and as you might think, you only to do that once, otherwise it makes no sense.

On the other hand, for the application I am developing, I only wanted to do one lookup, so it made no sense to load this file in memory. It just won’t speed up anything, and will load 1MB into memory.

My solution has been to update this library to allow two modes of operations. The first mode behaves the same way the original library, it loads everything to memory and it will work better if you are going to do hundreds of lookups. The second mode is access to disk for each lookup. This mode will work better if you are only going to do  a few lookups.

Here you have pygeoip.py with the changes I’ve made. For convenience, you can use disk_lookup:

pygeoip.disk_lookup (remote_addr)

This function works faster and consumes less resources but you have to use it when you want to do only a couple of lookups.

I want to congratulate David Wilson, the author of this library, because it has been really  easy to implement all the changes and improvements (of course I’ve sent him an e-mail with the changes, but now is up to him to include them or not).

Trackback URL

, ,

  1. Tom
    13/10/2011 at 7:14 pm Permalink

    Your data is wrong. Entire subnet 188.165.0.0 /16 is chopped between several countries, but you report all of them as France. E.g. 188.165.16.0/21 is in Poland (see https://apps.db.ripe.net/search/query.html?searchtext=188.165.16.0&search%253AdoSearch=Search )