Python client for the Geomelon API — cities, countries, regions, and languages with multilingual support
Project description
geomelon
Python client for the Geomelon API — cities, countries, regions, and languages with multilingual support (50+ languages).
- Zero dependencies — standard library only (
urllib) - Python 3.8+ — tested on 3.8 through 3.14
- Fully typed — dataclass models,
py.typedmarker, works with mypy/pyright - Sync API, one sub-client per resource, mirroring the TypeScript client
Install
pip install geomelon
Try it — no API key needed
City autocomplete via the free oneshot endpoint, zero signup:
from geomelon import GeomelonClient
client = GeomelonClient() # no key
for city in client.oneshot.search("es", "es", "barc"):
print(city.name, city.population, city.emoji)
# Barcelona 1620343 🇪🇸
search(iso, lang, prefix) takes an ISO 3166-1 alpha-2 country code, a BCP 47 language code, and the city-name prefix as the user typed it — the server normalizes case, punctuation, and diacritics ("Sant Cugat", "barç", and "barc" all work). Everything else (full-text search, filters, coordinates, countries, regions, translations) requires an API key.
Quickstart
Get an API key from RapidAPI.
from geomelon import GeomelonClient
client = GeomelonClient(api_key="YOUR_RAPIDAPI_KEY")
# Prefix search with multilingual names
cities = client.cities.search(name="barc", country_code="ES", preferred_languages="es,en")
for city in cities:
print(city.name, city.population, city.country_emoji)
# Barcelona 1620343 🇪🇸
# Single city by UUID
barcelona = client.cities.get("964512d1-f150-4876-87ec-0ba47aef694a")
print(barcelona.time_zone) # Europe/Madrid
print(barcelona.translations[0]) # CityTranslation(language='es', name='Barcelona')
# Nearest cities to coordinates
nearby = client.cities.by_coordinates_closest(41.3828, 2.1769, preferred_languages="es")
# Countries, regions, languages
spain = client.countries.get("a1e06cc1-817c-429f-84f4-6ab51dac9bfa")
print(spain.iso_code, len(spain.regions))
# Distance between two cities (km)
dist = client.cities.distance(city1="<uuid-1>", city2="<uuid-2>")
print(dist.distance_km)
# Oneshot: pre-built static prefix search (fastest path)
results = client.oneshot.search("es", "es", "ba")
With an API key, oneshot requests route through the RapidAPI gateway and count toward your plan. Pass free_oneshot=True to send them to the free keyless host instead:
client = GeomelonClient(api_key="YOUR_RAPIDAPI_KEY", free_oneshot=True)
API surface
| Sub-client | Methods |
|---|---|
client.cities |
search, get, translations, settlement_types, distance, by_coordinates_closest, by_coordinates_largest |
client.countries |
list, get, translations, regions |
client.regions |
list, get, translations |
client.languages |
list, get |
client.oneshot |
search |
All method parameters are keyword arguments in snake_case; they map 1:1 to the API's camelCase query parameters (country_code → countryCode). None parameters are omitted from the request. Response models are dataclasses with snake_case fields; unknown response fields are ignored, so API additions never break older client versions.
Error handling
All failures raise GeomelonError:
from geomelon import GeomelonClient, GeomelonError
client = GeomelonClient(api_key="YOUR_RAPIDAPI_KEY")
try:
client.cities.search(name="barc")
except GeomelonError as err:
if err.is_rate_limited: # HTTP 429
...
print(err.status, err.body, err.url)
status is None for network-level failures (DNS, timeout, connection refused).
Configuration
GeomelonClient(
api_key="...", # optional; omit for free-oneshot-only mode
host="geomelon.p.rapidapi.com", # override for staging/custom gateways
timeout=30.0, # seconds, per request
free_oneshot=False, # route oneshot to the keyless host even with a key
)
Calling a keyed endpoint on a keyless client raises GeomelonError immediately (no network request) with a message pointing to the RapidAPI signup.
Development
python -m unittest discover -s tests -v # run tests (no dev dependencies needed)
python -m build # build sdist + wheel (pip install build)
Publishing runs through GitHub Actions with PyPI trusted publishing on GitHub release — see .github/workflows/publish.yml.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file geomelon-1.0.0.tar.gz.
File metadata
- Download URL: geomelon-1.0.0.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a0e7067cc4f5e9719c49a9ceccc659d54f7038a989d309e6a630b4d06e5a600
|
|
| MD5 |
db5af14c753d08d25c37840d17490f49
|
|
| BLAKE2b-256 |
63c995a88d7ced16cc0e081a41357cec81a669dd548a4554564747447a6f3a43
|
Provenance
The following attestation bundles were made for geomelon-1.0.0.tar.gz:
Publisher:
publish.yml on 930m310n/python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
geomelon-1.0.0.tar.gz -
Subject digest:
2a0e7067cc4f5e9719c49a9ceccc659d54f7038a989d309e6a630b4d06e5a600 - Sigstore transparency entry: 2190901387
- Sigstore integration time:
-
Permalink:
930m310n/python@4a1d052404188c7e4ebda15144899aacda81cbf2 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/930m310n
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4a1d052404188c7e4ebda15144899aacda81cbf2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file geomelon-1.0.0-py3-none-any.whl.
File metadata
- Download URL: geomelon-1.0.0-py3-none-any.whl
- Upload date:
- Size: 9.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d05e0f4466c1c5cb2ff39ed5b809222674d3fddd1d96ddce2a27c57dda8f5a38
|
|
| MD5 |
c18ee5a7743511532ea1a0a912536b7d
|
|
| BLAKE2b-256 |
8adefcb437b1321ea5eda637403c9ffbea2b1870dfab013d10cdc54ad45e5f07
|
Provenance
The following attestation bundles were made for geomelon-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on 930m310n/python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
geomelon-1.0.0-py3-none-any.whl -
Subject digest:
d05e0f4466c1c5cb2ff39ed5b809222674d3fddd1d96ddce2a27c57dda8f5a38 - Sigstore transparency entry: 2190901437
- Sigstore integration time:
-
Permalink:
930m310n/python@4a1d052404188c7e4ebda15144899aacda81cbf2 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/930m310n
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4a1d052404188c7e4ebda15144899aacda81cbf2 -
Trigger Event:
release
-
Statement type: