Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion Changes.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
v1.0.0 Sat May 2 2026
Extracted from the `opencage` Python package; the CLI is now a standalone
`opencage-cli` distribution that depends on `opencage>=3.3.1` from PyPI.
No feature changes. Internal Python module renamed to `opencage_cli`.
Vendored two small helpers (`_query_for_reverse_geocoding`, `_floatify_latlng`)
from `opencage.geocoder` as private methods of `OpenCageBatchGeocoder` so the
CLI no longer depends on the library's private API.

== Below: changelog from when the CLI shipped inside the `opencage` package ==

v3.3.2 Sun Jun 08 2026
Improve validation of the host domain parameter
Improve validation of the host domain parameter (library-only change)

v3.3.1 Sun Mar 29 2026
Validate the host domain parameter. Should be opencagedata.com subdomain or localhost
Expand Down
140 changes: 24 additions & 116 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,131 +1,30 @@
# OpenCage Geocoding Module for Python
# OpenCage CLI

A Python module to access the [OpenCage Geocoding API](https://opencagedata.com/).
A command-line tool for the [OpenCage Geocoding API](https://opencagedata.com/), for forward and reverse geocoding of CSV files.

## Build Status / Code Quality / etc

[![PyPI version](https://badge.fury.io/py/opencage.svg)](https://badge.fury.io/py/opencage)
[![Downloads](https://pepy.tech/badge/opencage/month)](https://pepy.tech/project/opencage)
[![Versions](https://img.shields.io/pypi/pyversions/opencage)](https://pypi.org/project/opencage/)
![GitHub contributors](https://img.shields.io/github/contributors/opencagedata/python-opencage-geocoder)
[![Build Status](https://github.com/OpenCageData/python-opencage-geocoder/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/OpenCageData/python-opencage-geocoder/actions/workflows/build.yml)
![Mastodon Follow](https://img.shields.io/mastodon/follow/109287663468501769?domain=https%3A%2F%2Fen.osm.town%2F&style=social)
[![PyPI version](https://badge.fury.io/py/opencage-cli.svg)](https://badge.fury.io/py/opencage-cli)
[![Versions](https://img.shields.io/pypi/pyversions/opencage-cli)](https://pypi.org/project/opencage-cli/)
[![Build Status](https://github.com/OpenCageData/opencage-cli/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/OpenCageData/opencage-cli/actions/workflows/build.yml)

## Tutorials
## Tutorial

You can find a [comprehensive tutorial for using this module on the OpenCage site](https://opencagedata.com/tutorials/geocode-in-python).
See the [CLI tutorial on the OpenCage site](https://opencagedata.com/tutorials/geocode-commandline) for a full walk-through.

There are two brief video tutorials on YouTube, one [covering forward geocoding](https://www.youtube.com/watch?v=9bXu8-LPr5c), one [covering reverse geocoding](https://www.youtube.com/watch?v=u-kkE4yA-z0).
## Installation

The module installs an `opencage` CLI tool for geocoding files. Check `opencage --help` or the [CLI tutorial](https://opencagedata.com/tutorials/geocode-commandline).

## Working with AI / Agent Skill

There is an [Agent Skill for working with the OpenCage Geocoding API](https://github.com/OpenCageData/opencage-skills/) which includes a reference file for developing in Python using this module.

## Usage

Supports Python 3.9 or newer. Starting opencage version 3.0 depends on asyncio package.

Install the module:
Supports Python 3.9 or newer.

```bash
pip install opencage
```

Load the module:

```python
from opencage.geocoder import OpenCageGeocode
```

Create an instance of the geocoder module, passing a valid OpenCage Data Geocoder API key
as a parameter to the geocoder modules's constructor:

```python
key = 'your-api-key-here'
geocoder = OpenCageGeocode(key)
```

Pass a string containing the query or address to be geocoded to the modules' `geocode` method:

```python
query = '82 Clerkenwell Road, London'
results = geocoder.geocode(query)
```

You can add [additional parameters](https://opencagedata.com/api#forward-opt):

```python
results = geocoder.geocode('London', no_annotations=1, language='es')
```

For example you can use the proximity parameter to provide the geocoder with a hint:

```python
results = geocoder.geocode('London', proximity='42.828576, -81.406643')
print(results[0]['formatted'])
# u'London, ON N6A 3M8, Canada'
pip install opencage-cli
```

### Reverse geocoding

Turn a lat/long into an address with the `reverse_geocode` method:
This installs an `opencage` executable on your `PATH`. The Python geocoding library it uses (the `opencage` package on PyPI) is pulled in as a dependency.

```python
result = geocoder.reverse_geocode(51.51024, -0.10303)
```

### Sessions

You can reuse your HTTP connection for multiple requests by
using a `with` block. This can help performance when making
a lot of requests:

```python
queries = ['82 Clerkenwell Road, London', ...]
with OpenCageGeocode(key) as geocoder:
# Queries reuse the same HTTP connection
results = [geocoder.geocode(query) for query in queries]
```

### Asyncronous requests

You can run requests in parallel with the `geocode_async` and `reverse_geocode_async`
method which have the same parameters and response as their synronous counterparts.
You will need at least Python 3.8 and the `asyncio` and `aiohttp` packages installed.

```python
async with OpenCageGeocode(key) as geocoder:
results = await geocoder.geocode_async(address)
```

For a more complete example and links to futher tutorials on asyncronous IO see
`batch.py` in the `examples` directory.

### Non-SSL API use

If you have trouble accesing the OpenCage API with https, e.g. issues with OpenSSL
libraries in your enviroment, then you can set the 'http' protocol instead. Please
understand that the connection to the OpenCage API will no longer be encrypted.

```python
geocoder = OpenCageGeocode('your-api-key', 'http')
```

### Exceptions

If anything goes wrong, then an exception will be raised:

- `InvalidInputError` for non-unicode query strings
- `NotAuthorizedError` if API key is missing, invalid syntax or disabled
- `ForbiddenError` API key is blocked or suspended
- `RateLimitExceededError` if you go past your rate limit
- `UnknownError` if there's some problem with the API (bad results, 500 status code, etc)

## Command-line batch geocoding
## Usage

Use `opencage forward` or `opencage reverse`
Use `opencage forward` or `opencage reverse`:

```
opencage forward --help
Expand All @@ -137,10 +36,10 @@ options:
--output FILENAME Output file name
--headers If the first row should be treated as a header row
--input-columns Comma-separated list of integers (default '1')
--add-columns Comma-separated list of output columns (default 'lat,lng,_type,_category,country_code,country,state,county,_normalized_city,postcode,road,house_number,confidence,formatted,json,status')
--add-columns Comma-separated list of output columns (default 'lat,lng,_type,_category,country_code,country,state,county,_normalized_city,postcode,road,house_number,confidence,formatted')
--workers Number of parallel geocoding requests (default 1)
--timeout Timeout in seconds (default 10)
--retries Number of retries (default 5)
--retries Number of retries (default 10)
--api-domain API domain (default api.opencagedata.com)
--optional-api-params
Extra parameters for each request (e.g. language=fr,no_dedupe=1)
Expand All @@ -155,6 +54,15 @@ options:

<img src="batch-progress.gif"/>

See [`examples/addresses.csv`](examples/addresses.csv) for sample input.

## Working with AI / Agent Skill

There is an [Agent Skill for working with the OpenCage Geocoding API](https://github.com/OpenCageData/opencage-skills/).

## Python library

If you want to call the OpenCage API directly from Python rather than via this CLI, install [the `opencage` library](https://pypi.org/project/opencage/) — `pip install opencage`.

## Copyright & License

Expand Down
2 changes: 1 addition & 1 deletion Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Vagrant.configure("2") do |config|
config.vm.box = 'gutehall/ubuntu24-04'
end

config.vm.synced_folder ".", "/home/vagrant/python-opencage-geocoder"
config.vm.synced_folder ".", "/home/vagrant/opencage-cli"

# provision using a simple shell script
config.vm.provision :shell, path: "vagrant-provision.sh", privileged: false
Expand Down
139 changes: 0 additions & 139 deletions examples/batch.py

This file was deleted.

21 changes: 0 additions & 21 deletions examples/demo.py

This file was deleted.

27 changes: 0 additions & 27 deletions examples/flask_demo.py

This file was deleted.

6 changes: 0 additions & 6 deletions opencage/__init__.py

This file was deleted.

Loading