A Python module for returning data about countries, ISO info, and states/provinces within them.
Project description
Countryinfo
A lightweight Python library for accessing comprehensive country data — including ISO codes, states/provinces, capital cities, currencies, languages, and other geographic information.
☕ Support This Project
This project is developed and maintained during the author's free time. If you find it useful and would like to support its continued development, consider buying a coffee or sponsoring the project. Every bit of support helps keep the project maintained and improving ❤️
Table of Contents
- Countryinfo
- Table of Contents
- Install
- Quick Start
- Constructor
- API Reference
- Country lookup
- .info()
- .name()
- .iso()
- .alt_spellings()
- .area()
- .borders()
- .neighbors()
- .calling_codes()
- .capital()
- .capital_latlng()
- .currencies()
- .demonym()
- .geo_json()
- .languages()
- .latlng()
- .native_name()
- .population()
- .provinces()
- .region()
- .subregion()
- .timezones()
- .timezone_names()
- .current_utc_offset()
- .tld()
- .translations()
- .wiki()
- .google()
- Filter & Reverse Queries
- Optional Extras
- CLI
- Errors
- Contributing
- Special Thanks
- Disclaimer
- License
Install
pip install countryinfo
With optional extras:
pip install "countryinfo[fuzzy]" # typo-tolerant country lookup
pip install "countryinfo[pydantic]" # Pydantic v2 typed models
pip install "countryinfo[all]" # everything above
Using Poetry:
poetry add countryinfo
poetry add "countryinfo[fuzzy,pydantic]"
Install from source:
git clone https://github.com/porimol/countryinfo.git
cd countryinfo
poetry install
Quick Start
from countryinfo import CountryInfo
country = CountryInfo("Singapore")
print(country.capital()) # Singapore
print(country.iso(2)) # SG
print(country.population()) # 5469700
print(country.neighbors()) # [] — island, no land borders
Constructor
CountryInfo accepts any of the following identifiers (case-insensitive):
CountryInfo("Singapore") # English name
CountryInfo("singapore") # lowercase — OK
CountryInfo("SG") # ISO alpha-2
CountryInfo("SGP") # ISO alpha-3
CountryInfo("702") # ISO numeric (string or int)
CountryInfo(702) # ISO numeric (int)
CountryInfo("Singapura") # native / alternate name
CountryInfo("Republic of Singapore") # full official name
Raises ValueError if no identifier is supplied.
Raises CountryNotFoundError (a LookupError) if the identifier cannot be resolved.
API Reference
To access country details, first create a CountryInfo instance using a country name or code. Then, use the methods listed below to retrieve specific properties.
Country lookup
from countryinfo import CountryInfo
sg = CountryInfo("SG") # ISO alpha-2
de = CountryInfo("DEU") # ISO alpha-3
fr = CountryInfo(250) # ISO numeric
.info()
Returns all available data for the country.
CountryInfo("Singapore").info()
# {
# 'name': 'Singapore',
# 'ISO': {'alpha2': 'SG', 'alpha3': 'SGP', 'numeric': '702'},
# 'altSpellings': ['SG', 'Singapura', 'Republic of Singapore', ...],
# 'area': 710,
# 'borders': [],
# 'callingCodes': ['65'],
# 'capital': 'Singapore',
# 'capital_latlng': [1.357107, 103.819499],
# 'currencies': ['SGD'],
# 'demonym': 'Singaporean',
# 'languages': ['en', 'ms', 'ta', 'zh'],
# 'latlng': [1.36666666, 103.8],
# 'nativeName': 'Singapore',
# 'population': 5469700,
# 'provinces': ['Singapore'],
# 'region': 'Asia',
# 'subregion': 'South-eastern Asia',
# 'timezones': ['UTC+08:00'],
# 'timezoneNames': ['Asia/Singapore'],
# 'tld': ['.sg'],
# 'translations': {'de': 'Singapur', 'es': 'Singapur', ...},
# 'wiki': 'http://en.wikipedia.org/wiki/singapore',
# 'google': 'https://www.google.com/search?q=Singapore',
# }
# Similar can also be achieved via country code or any
# alternate name of a country. For example, Singapur
# would be:
country = CountryInfo('SG')
country.info()
.name()
Returns the English country name (proper casing).
CountryInfo("SG").name() # 'Singapore'
CountryInfo("SGP").name() # 'Singapore'
.iso()
Returns ISO 3166-1 codes. Now includes numeric code.
country = CountryInfo("Singapore")
country.iso() # {'alpha2': 'SG', 'alpha3': 'SGP', 'numeric': '702'}
country.iso(2) # 'SG'
country.iso(3) # 'SGP'
.alt_spellings()
Returns alternate spellings for the name of a specified country
CountryInfo("Singapore").alt_spellings()
# ['SG', 'Singapura', 'Republic of Singapore', ...]
.area()
Returns area (km²) for a specified country
CountryInfo("Singapore").area() # 710
# or
country = CountryInfo("Singapore")
country.area() # 710
.borders()
Bordering countries as ISO alpha-3 codes.
CountryInfo("Germany").borders()
# ['AUT', 'BEL', 'CHE', 'CZE', 'DNK', 'FRA', 'LUX', 'NLD', 'POL']
# or
country = CountryInfo("Singapore")
country.borders()
.neighbors()
Bordering countries as CountryInfo objects. New in v1.0.0.
for neighbor in CountryInfo("France").neighbors():
print(neighbor.name(), neighbor.capital())
# Germany Berlin
# Belgium Brussels
# ...
.calling_codes()
Returns international calling codes for a specified country
CountryInfo("Singapore").calling_codes() # ['65']
# or
country = CountryInfo("Singapore")
country.calling_codes() # ['65']
.capital()
Returns capital city for a specified country
CountryInfo("Singapore").capital() # 'Singapore'
# or
country = CountryInfo("Singapore")
country.capital() # 'Singapore'
.capital_latlng()
Returns capital city latitude and longitude for a specified country
CountryInfo("Singapore").capital_latlng() # [1.357107, 103.819499]
# or
country = CountryInfo("Singapore")
country.capital_latlng() # [1.357107, 103.819499]
.currencies()
CountryInfo("Singapore").currencies() # ['SGD']
# or
country = CountryInfo("Singapore")
country.currencies() # ['SGD']
.demonym()
CountryInfo("Singapore").demonym() # 'Singaporean'
# or
country = CountryInfo("Singapore")
country.demonym() # 'Singaporean'
.geo_json()
Returns GeoJSON FeatureCollection for the country boundary.
CountryInfo("Bangladesh").geo_json()
# {'type': 'FeatureCollection', 'features': [...]}
# or
country = CountryInfo("Singapore")
country.geo_json()
# {'type': 'FeatureCollection', 'features': [...]}
.languages()
ISO 639-1 language codes.
CountryInfo("Singapore").languages() # ['en', 'ms', 'ta', 'zh']
# or
country = CountryInfo("Singapore")
country.languages() # ['en', 'ms', 'ta', 'zh']
.latlng()
Approximate country centre coordinates.
CountryInfo("Singapore").latlng() # [1.36666666, 103.8]
# or
country = CountryInfo("Singapore")
country.latlng()
.native_name()
Returns the name of the country in its native tongue
CountryInfo("Germany").native_name() # 'Deutschland'
# or
country = CountryInfo("Germany")
country.native_name() # 'Deutschland'
.population()
CountryInfo("Singapore").population() # 5469700
# or
country = CountryInfo("Singapore")
country.population() # 5469700
.provinces()
Return provinces list
CountryInfo("Singapore").provinces() # ['Singapore']
# or
country = CountryInfo("Singapore")
country.provinces() # ['Singapore']
.region()
CountryInfo("Singapore").region() # 'Asia'
# or
country = CountryInfo("Singapore")
country.region() # 'Asia'
.subregion()
CountryInfo("Singapore").subregion() # 'South-eastern Asia'
# or
country = CountryInfo("Singapore")
country.subregion() # 'South-eastern Asia'
.timezones()
Static UTC offset strings.
CountryInfo("Singapore").timezones() # ['UTC+08:00']
CountryInfo("Switzerland").timezones() # ['UTC+01:00', 'UTC+02:00']
# or
country = CountryInfo("Singapore")
country.timezones() # ['UTC+08:00']
.timezone_names()
IANA timezone names. New in v1.0.0.
CountryInfo("Singapore").timezone_names() # ['Asia/Singapore']
CountryInfo("United States").timezone_names()
# ['America/New_York', 'America/Chicago', 'America/Denver', ...]
# or
country = CountryInfo("Singapore")
country.timezone_names() # ['Asia/Singapore']
.current_utc_offset()
DST-aware current UTC offset(s). Uses zoneinfo (stdlib). New in v1.0.0.
CountryInfo("Singapore").current_utc_offset() # ['+08:00']
CountryInfo("Switzerland").current_utc_offset() # ['+01:00'] or ['+02:00'] depending on season
CountryInfo("United States").current_utc_offset()
# ['-05:00', '-06:00', '-07:00', '-08:00', '-09:00', '-10:00']
# or
country = CountryInfo("Singapore")
country.current_utc_offset() # ['+08:00']
.tld()
CountryInfo("Singapore").tld() # ['.sg']
# or
country = CountryInfo("Singapore")
country.tld() # ['.sg']
.translations()
Country name in major languages.
CountryInfo("Singapore").translations()
# {'de': 'Singapur', 'es': 'Singapur', 'fr': 'Singapour', 'it': 'Singapore', 'ja': 'シンガポール'}
# or
country = CountryInfo("Singapore")
country.translations()
.wiki()
CountryInfo("Singapore").wiki()
# 'http://en.wikipedia.org/wiki/singapore'
# or
country = CountryInfo("Singapore")
country.wiki()
.google()
CountryInfo("Singapore").google()
# 'https://www.google.com/search?q=Singapore'
# or
country = CountryInfo("Singapore")
country.google()
Filter & Reverse Queries
all_countries()
Returns every country as a list of CountryInfo objects. New in v1.0.0.
from countryinfo import all_countries
countries = all_countries()
capitals = [c.capital() for c in countries]
filter_countries()
Filter all countries by field. New in v1.0.0.
from countryinfo import filter_countries
# All countries in Asia
asia = filter_countries(region="Asia")
# All Arabic-speaking countries
arabic = filter_countries(language="ar")
# Eurozone countries
eurozone = filter_countries(currency="EUR")
# Countries that border France
near_france = filter_countries(border="FRA")
# Combine filters (AND logic)
result = filter_countries(region="Europe", currency="EUR")
for c in result:
print(c.name(), c.capital())
Supported keyword arguments: region, subregion, language, currency, border, calling_code, tld.
CountryInfo.all()
Returns raw data for all countries as a dict (backward-compatible classmethod).
from countryinfo import CountryInfo
data = CountryInfo.all() # {lowercase_name: {...}, ...}
Optional Extras
Fuzzy / typo-tolerant lookup
pip install "countryinfo[fuzzy]"
Once installed, the constructor automatically falls back to fuzzy matching when an exact match fails:
CountryInfo("Singaproe").name() # 'Singapore' (typo corrected)
CountryInfo("Germny").name() # 'Germany'
Pydantic models
pip install "countryinfo[pydantic]"
country = CountryInfo("Singapore")
model = country.model()
print(model.name) # Singapore
print(model.iso.alpha2) # SG
print(model.iso.numeric) # 702
print(model.capital) # Singapore
print(model.population) # 5469700
CLI
A command-line tool is included.
# Full country info
countryinfo Singapore
# Specific field
countryinfo Singapore --field capital
countryinfo SG --field iso
countryinfo 702 --field current_utc_offset
# Filter
countryinfo --filter region=Asia
countryinfo --filter currency=EUR
countryinfo --filter region=Europe currency=EUR
# JSON output
countryinfo Singapore --json
countryinfo --filter language=ar --json
Errors
from countryinfo import CountryInfo, CountryNotFoundError
try:
country = CountryInfo("Xanadu")
except CountryNotFoundError as e:
print(e) # Country not found: 'Xanadu'. Pass a country name, ISO ...
# CountryNotFoundError is a LookupError
try:
CountryInfo(None)
except ValueError:
pass # None or empty string raises ValueError
Contributing
Contributions are welcome — bug reports, data corrections, and pull requests.
See the list of contributors who have participated in this project.
How to contribute
- Fork the repository on GitHub.
- Clone your fork locally.
- Create a new branch from
main. - Make your changes and add/update tests in
tests/. - Run the test suite:
poetry run pytest tests/ -v - Open a pull request against
main.
Data corrections: Each country is a single JSON file in
countryinfo/data/. Edit the relevant file and open a PR — no Python changes needed for data-only fixes.
Special Thanks
Special thanks to johan for world.geo.json, which made the GeoJSON data possible.
Inspired by countryjs by Oz Haven.
Disclaimer
This library is maintained in the contributor's free time. Data is sourced primarily from Wikipedia. If you find an error, please open an issue.
License
MIT License — Copyright (c) 2018, Porimol Chandro
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 countryinfo-1.0.1.tar.gz.
File metadata
- Download URL: countryinfo-1.0.1.tar.gz
- Upload date:
- Size: 245.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
300b378f6371a2a7ee804ecdc0ad6ebe29e3647b8ca341d83cfebd9ce6934261
|
|
| MD5 |
143a8f33ec2345943e00db2f17820e04
|
|
| BLAKE2b-256 |
31a32613df4f0707c4ba6fc93a1fcb8659fc23551aeab0314f6ceed56c31a86c
|
Provenance
The following attestation bundles were made for countryinfo-1.0.1.tar.gz:
Publisher:
publish-pypi.yml on porimol/countryinfo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
countryinfo-1.0.1.tar.gz -
Subject digest:
300b378f6371a2a7ee804ecdc0ad6ebe29e3647b8ca341d83cfebd9ce6934261 - Sigstore transparency entry: 1056309643
- Sigstore integration time:
-
Permalink:
porimol/countryinfo@ee717211517e146e7bf6697cf5af2f85bb57dbf8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/porimol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@ee717211517e146e7bf6697cf5af2f85bb57dbf8 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file countryinfo-1.0.1-py3-none-any.whl.
File metadata
- Download URL: countryinfo-1.0.1-py3-none-any.whl
- Upload date:
- Size: 380.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b02f6f534f0a3b9cdc73fba7e08f247e39826acfa54bf080f8e4eba812066350
|
|
| MD5 |
01c98f14c119619e6a03a7d0ff745421
|
|
| BLAKE2b-256 |
6be59aec9a663aaeeacce15511dbae33b5abca31152779f2cb1c5be89fd2eb59
|
Provenance
The following attestation bundles were made for countryinfo-1.0.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on porimol/countryinfo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
countryinfo-1.0.1-py3-none-any.whl -
Subject digest:
b02f6f534f0a3b9cdc73fba7e08f247e39826acfa54bf080f8e4eba812066350 - Sigstore transparency entry: 1056309770
- Sigstore integration time:
-
Permalink:
porimol/countryinfo@ee717211517e146e7bf6697cf5af2f85bb57dbf8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/porimol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@ee717211517e146e7bf6697cf5af2f85bb57dbf8 -
Trigger Event:
workflow_dispatch
-
Statement type: