This book covers the use of Redis, an in-memory database/data structure server.

open all | close all

5.3.2 Looking up cities

To support looking up IP addresses, we added integer scores to a ZSET to represent the
beginning of IP address ranges for a given city ID. In order to find a city given an IP
address, we map the IP address to a similarly calculated score and then find the city ID
that has the largest starting IP address less than or equal to the IP address we pass. We
can use ZREVRANGEBYSCORE with the optional START and NUM arguments set to 0 and 1,
respectively, to fetch this information. After we’ve discovered the city ID, we can fetch
the city information from our HASH. Our function for finding which city an IP address
is in can be seen next.

Listing 5.12The find_city_by_ip() function
def find_city_by_ip(conn, ip_address):

   if isinstance(ip_address, str):
      ip_address = ip_to_score(ip_address)

Convert the IP address to a score for zrevrangebyscore.

   city_id = conn.zrevrangebyscore(
      'ip2cityid:', ip_address, 0, start=0, num=1)

Find the unique city ID.

   if not city_id:
      return None

   city_id = city_id[0].partition('_')[0]

Convert the unique city ID to the common city ID.

   return json.loads(conn.hget('cityid2city:', city_id))

Fetch the city information from the HASH.

We can now look up city information based on IP address and begin to analyze where
our users are coming from. This method of converting data into integers for use with
a ZSET is useful, and can greatly simplify the discovery of individual items or ranges.
We’ll talk more about these kinds of data transformations in chapter 7. But for now, let’s
look at how we can use Redis to help us find and connect to other servers and services.