Python Geocoding Tutorial

The code examples below will use your API key once you log in.

This is a tutorial for using the OpenCage Geocoding API in Python.

Before we dive in to the tutorial ...

You will need to sign up for an OpenCage API key.

Spend two minutes ...

Ok, ready?

Install the OpenCage Python module

Compatible with Python version 3.

pip3 install opencage

Geocoding coordinates

from opencage.geocoder import OpenCageGeocode
from pprint import pprint

key = 'YOUR-API-KEY'
geocoder = OpenCageGeocode(key)

results = geocoder.reverse_geocode(44.8303087, -0.5761911)
pprint(results)
# [{'components': {'city': 'Bordeaux',
#                  'country': 'France',
#                  'country_code': 'fr',
#                  'county': 'Bordeaux',
#                  'house_number': '11',
#                  'political_union': 'European Union',
#                  'postcode': '33800',
#                  'road': 'Rue Sauteyron',
#                  'state': 'New Aquitaine',
#                  'suburb': 'Bordeaux Sud'},
#   'formatted': '11 Rue Sauteyron, 33800 Bordeaux, France',
#   'geometry': {'lat': 44.8303087, 'lng': -0.5761911}}]

Set output language, error handling

from opencage.geocoder import OpenCageGeocode
from opencage.geocoder import InvalidInputError, RateLimitExceededError, UnknownError

key = 'YOUR-API-KEY'
geocoder = OpenCageGeocode(key)

try:
  results = geocoder.reverse_geocode(44.8303087, -0.5761911, language='de', no_annotations='1')
  if results and len(results):
    print(results[0]['formatted'])
    # 11 Rue Sauteyron, 33800 Bordeaux, Frankreich
except RateLimitExceededError as ex:
  print(ex)
  # Your rate limit has expired. It will reset to 2500 on 2020-10-08T00:00:00
  # Upgrade your plan on https://opencagedata.com/pricing or wait until
  # the next day https://opencagedata.com/clock
except InvalidInputError as ex:
  # this happens for example with invalid unicode in the input data

Lookup coordinates from postal address

from opencage.geocoder import OpenCageGeocode

key = 'YOUR-API-KEY'
geocoder = OpenCageGeocode(key)

query = u'Bosutska ulica 10, Trnje, Zagreb, Croatia'
results = geocoder.geocode(query)

print(u'%f;%f;%s;%s' % (results[0]['geometry']['lat'], 
                        results[0]['geometry']['lng'],
                        results[0]['components']['country_code'],
                        results[0]['annotations']['timezone']['name']))
# 45.797095;15.982453;hr;Europe/Belgrade

Batch geocode a file of addresses

Create a file containing addresses
Madrid,Spain
Milan,Italy
Berlin,Germany
import sys
from opencage.geocoder import OpenCageGeocode

key = 'YOUR-API-KEY'
geocoder = OpenCageGeocode(key)
addressfile = 'addresses.txt'

try: 
  with open(addressfile,'r') as f:
    for line in f:
      address = line.strip()
      results = geocoder.geocode(address, no_annotations='1')

      if results and len(results):
        longitude = results[0]['geometry']['lng']
        latitude  = results[0]['geometry']['lat']
        print(u'%f;%f;%s' % (latitude, longitude, address))
        # 40.416705;-3.703582;Madrid,Spain
        # 45.466797;9.190498;Milan,Italy
        # 52.517037;13.388860;Berlin,Germany
      else:
        sys.stderr.write("not found: %s\n" % address)
except IOError:
  print('Error: File %s does not appear to exist.' % addressfile)
except RateLimitExceededError as ex:
  print(ex)
  # Your rate limit has expired. It will reset to 2500 at midnight UTC timezone
  # Upgrade on https://opencagedata.com/pricing

Running many parallel queries

By default the Python 'request' library will only run one HTTP request, even if you wrap the logic inside multipthreading or asyncronous calls. At low level it will block other HTTP requests.

Instead you should use the asyncio library for HTTP requests. We prepared a more complex code example of python parallel batch requests using a queue, task workers and automatic retry logic. We've used variations of the script for lists of 10s of millions of addresses.

Alternative Python modules

Further Reading

Start your free trial

2,500 API requests per day.

No credit card required.