iso3166-2
is a structured lightweight custom-built Python package, and accompanying RESTful API, that can be used to access all of the world's ISO 3166-2 subdivision data. A plethora of data attributes are available per country and subdivision including: name, local/other name, code, parent code, type, lat/longitude, flag & history. Currently, the package and API supports data from 250 countries/territories and >5000 subdivisions, according to the ISO 3166-1 & ISO 3166-2 standards, respectively. The software uses another custom-built Python package callediso3166-updates
to ensure all the subdivision data is accurate, reliable and up-to-date.
- A demo of the software and API is available here.
- The front-end API is available here.
- The documentation for the software & API is available here.
- A Medium article that dives deeper into
iso3166-2
is available here.
- Introduction
- Bespoke Features
- Requirements
- Installation
- Usage
- Documentation
- Latest Updates
- API
- Directories
- Issues or Contributing
- Contact
- References
- Support
The International Organisation for Standards defines codes for the names of countries, dependent territories, special areas of geographical interest, and their principal subdivisions [1]. The ISO 3166-2 defines codes for identifying the principal subdivisions (e.g. provinces, states, municipalities etc) of all countries coded in the ISO 3166-1. The official name of the standard is "Codes for the representation of names of countries and their subdivisions – Part 2: Country subdivision code." For some countries, codes are defined for more than one level of subdivisions.
Currently, this package and accompanying API support subdivision data from 250 officially assigned code elements within the ISO 3166-1, with 200 of these countries having recognised subdivisions (50 entires have 0 subdivisions), totalling 5,049 subdivisions across the whole dataset. Transitional reservations are not included and only 4 of the exceptional reservations, that have now been officially assigned, are included: AX (Aland Islands), GG (Guernsey), IM (Isle of Man) and JE (Jersey) [3]. The ISO 3166-2 was first published in 1998 and as of November 2023 there are 5,049 codes defined in it [2].
The full list of subdivision data attributes supported are:
- Code - ISO 3166-2 subdivision code
- Name - subdivision name
- Local/other name - subdivision name in local language or any alternative name/nickname it is commonly known by
- Parent Code - subdivision parent code
- Type - subdivision type, e.g. region, state, canton, parish etc
- Latitude/Longitude - subdivision coordinates
- Flag - subdivision flag from
iso3166-flag-icons
repo; this is another ISO 3166 related custom-built dataset of over 3500 regional/subdivision flags - History - historical updates/changes to the subdivision code and naming conventions, as per the custom-built
iso3166-updates
repo.
The primary motivation for building this software was for use in my iso3166-flag-icons
project. When building the dataset of flags, I found that some existing projects/softwares were inaccurate, outdated and or not maintained. As mentioned, the ISO 3166-2 is a dynamic and ever-changing standard therefore it can be difficult to maintain and keep up-to-date; although in the case for this software, that problem is largely alleviated thanks to the custom-built iso3166-updates
package (see below sections).
Furthermore, there are existing toolkits and datasets that offer a rich collection of regional attributes data, geonames for example. Although, many of these datasets are very large in size and difficult to parse, with an abundance of unessential data attributes.
Thus the aim during development was to build a structured, lightweight and up-to-date ISO 3166-2 dataset with the most sought data attributes that can be easily packaged into a Python package.
There are three main attributes supported by the software that make it stand out and add a significant amount of value and data per subdivision, in comparison to some the other iso3166-2 datasets, these are the local/other name, flag and history attributes.
One of the most important and bespoke attributes that the software supports, that many others do not, is the local/other name attribute. This attribute is built from a custom dataset of local language variants and alternative names/nicknames for the over 5000 subdivisions. In total there are >3700 local/other names for the >5000 subdivisions. Primarily, the attribute contains local language translations for the subdivisions, but many also include nicknames and alternative variants that the subdivision may be known by, either locally or globally.
For each local/other name, the ISO 639 3 letter language code is used to identify the language of the name. Some translations do not have available ISO 639 codes, therefore the Glottolog or other databases (e.g IETF) language codes are used. Some example local/other name entries are:
- Sindh (Pakistan PK-SD): "سِنْدھ (urd), Sindh (eng), SD (eng), Mehran/Gateway (eng), Bab-ul-Islam/Gateway of Islam (eng)"
- Central Singapore (Singapore SG-01): "Pusat Singapura (msa), 新加坡中部 (zho), மத்திய சிங்கப்பூர் (tam)"
- Bobonaro (East Timor TL-BO): "Bobonaru (tet), Buburnaru (tet), Tall eucalypt (eng)"
- Wyoming (USA US-WY) - "Equality State (eng), Cowboy State (eng), Big Wyoming (eng)"
The full dataset of local/other names is available in the repo here local_other_names.csv
The other equally important and bespoke/unique attribute that the software package supports is the flag
attribute, which is a link to the subdivision's flag on the iso3166-flag-icons
repo. This is another custom-built repository, (alongside iso3166-2
and iso3166-updates
) that stores a rich and comprehensive dataset of over 3500 individual subdivision flags.
The flags repo uses the iso3166-2
software to get the full list of ISO 3166-2 subdivision codes which is kept up-to-date and accurate via the iso3166-updates
software.
The history
attribute has any applicable historical updates/changes to the individual subdivisions, if applicable. The data source for this is another custom-built software package previously mentioned iso3166-updates
. This package keeps track of all the published changes that the ISO make to the ISO 3166 standard which include addition of new subdivisions, deletion of existing subdivisions or amendments to existing subdivisions. Thus iso3166-updates
helps ensure that the data in the iso3166-2
package is also kept up-to-date and accurate. If any updates are found for the subdivision a short description of the change, it's publication date as well as its source will be included.
Install the latest version of iso3166-2
via PyPi using pip:
pip install iso3166-2 --upgrade
All of the country's subdivision data and attributes are encapsulated into an instance of the Subdivisions class via the JSON object iso3166-2.json, which contains each country's ISO 3166-2 subdivision data. The data can be accessed after creating an instance of the Subdivisions class, with the instance being subscriptable such that data can be accessed via their ISO 3166-1 alpha-2, alpha-3 or numeric country codes. There also exist a plethora of additional functionalities around the subdivisision data. Below are some usage examples for the software.
Import and create instance of Subdivisions class:
from iso3166_2 import *
#create instance of Subdivisions class
iso = Subdivisions()
Get all ISO 3166-2 data for all countries:
iso.all
Get all subdivision data for a country, via their alpha-2, alpha-3 and numeric country codes:
canada_iso3166_2 = iso["CA"]
denmark_iso3166_2 = iso["DK"]
estonia_iso3166_2 = iso["EST"]
peru_iso3166_2 = iso["PER"]
fiji_haiti_iso3166_2 = iso["FJ, HT"]
fiji_haiti_guyana_iso3166_2 = iso["FJ, HTI, 328"]
Get subdivision's data, via its subdivision code:
iso["CA"]['CA-AB'] #Alberta subdivision
iso["DK"]['DK-81'] #Nordjylland subdivision
iso["EST"]['EE-899'] #Viljandi subdivision
iso["FJI"]['FJ-03'] #Cakaudrove subdivision
iso["PE"]["PE-LAL"] #La Libertad subdivision
iso["604"]['PE-AMA'] #Amarumayu subdivision
Get individual attribute values per subdivision:
iso["CA"]['CA-AB'].latLng #Alberta subdivision latitude/longitude
iso["DK"]['DK-81'].flag #Nordjylland subdivision flag URL
iso["PE"]['PE-LAL'].history #La Libertad subdivision updates history
iso["EST"]['EE-899'].name #Viljandi subdivision name
iso["FJI"]['FJ-03'].type #Cakaudrove subdivision type
iso["604"]['PE-AMA'].parentCode #Amarumayu subdivision
Get subset of subdivision attributes for all countries:
'''
If only a subset of the available default attributes are required per
subdivision, include them via the 'filter_attributes' input parameter
when creating an instance of the class. All attributes not included
in this list will be excluded.
'''
from iso3166_2 import *
#create instance of Subdivisions class
iso = Subdivisions(filter_attributes="flag,parentCode,type")
Searching for a specific subdivision via its subdivision name or local/other name attributes:
'''
The search functionality will search over all subdivisions in the object,
returning either a subdivision with the exact match or subdivisions whose names
approximately match the sought input name according to the likeness input parameter.
The likeness input parameter is a % similarity the input search terms have to be to
the subdivision names, with 100% being an exact match, vice versa. Reducing this
value will thus increase the search space and return more like results. You can
exclude the Match Score attribute in the search results by setting the excludeMatchScore
parameter to 1.
'''
from iso3166_2 import *
#create instance of Subdivisions class
iso = Subdivisions()
#searching for the Monaghan county in Ireland (IE-MN) - returning exact matching subdivision (likeness=100)
iso.search("Monaghan")
#searching for Castelo Branco district in Portugal (PT-05) - returning exact matching subdivision (likeness=100)
iso.search("Castelo Branco", likeness=100)
#searching for the Roche Caiman district in Seychelles (SC-25) - returning exact matching subdivision (likeness=100)
iso.search("Roche Caiman")
#searching for any subdivisions that have "Southern" in their name, using a likeness score of 80, exclude Match Score attribute
iso.search("Southern", likeness_score=80, exclude_match_score=1)
#searching for any subdivisions that have "City" in their name or localOtherName attributes, using a likeness score of 40%
iso.search("City", likeness=40, local_other_name_search=True)
#searching for state of Texas and French Department Meuse - both subdivision objects will be returned, only including the subdivision type and name attributes
iso.search("Texas, Meuse", filter_attributes="name,type")
Adding a custom subdivision to the iso3166-2 object:
'''
The context for this functionality is similar to that of the user-assigned
code elements of the ISO 3166-1 standard. Custom subdivisions and subdivision
codes can be used for in-house/bespoke applications that are using the
iso3166-2 software but require additional custom subdivisions to be represented.
You can also add custom attributes for the custom subdivision, e.g population,
area, gdp etc, via the custom_attribute parameter. You can save the custom
object with the new subdivision data added to a custom file via the save_new
and save_new_filename parameters.
'''
from iso3166_2 import *
#create instance of Subdivisions class
iso = Subdivisions()
#adding custom Belfast province to Ireland
iso.custom_subdivision("IE", "IE-BF", name="Belfast", local_other_name="Béal Feirste", type_="province", lat_lng=[54.596, -5.931], parent_code=None, flag=None)
#adding custom Alaska province to Russia with additional population and area attribute values, save object to new file
iso.custom_subdivision("RU", "RU-ASK", name="Alaska Oblast", local_other_name="Аляска", type_="Republic", lat_lng=[63.588, 154.493], parent_code=None, flag=None,
custom_attributes={"population": "733,583", "gini": "0.43", "gdpPerCapita": "71,996"}, save_new=1, save_new_filename="ru-ask-custom.json")
#adding custom Republic of Molossia state to United States
iso.custom_subdivision("US", "US-ML", name="Republic of Molossia", local_other_name="", type_="State", lat_lng=[39.236, -119.588], parent_code=None, flag="https://upload.wikimedia.org/wikipedia/commons/c/c3/Flag_of_the_Republic_of_Molossia.svg")
#deleting above custom subdivisions from object
iso.custom_subdivision("IE", "IE-BF", delete=1)
iso.custom_subdivision("US", "US-ML", delete=1)
iso.custom_subdivision("RU", "RU-ASK", delete=1)
Check for the latest updates data from the repository:
'''
Compare the subdivision data in the current installed version of the
iso3166-2 software with the most up-to-date and accurate version on
the repository. If there are any difference between these objects,
they will be output.
'''
iso.check_for_updates()
Get total number of subdivisions in object:
len(iso)
Get size of dataset in MB:
iso.__sizeof__()
Documentation for installation and usage of the software and API is available on the readthedocs platform:
https://iso3166-2.readthedocs.io/en/latest/
An important thing to note about the ISO 3166-2 and its subdivision codes/names is that changes are made consistently to it, from a small subdivision name change to an addition/deletion of a whole subdivision. These changes can happen due for a variety of geopolitical and administrative reasons. Therefore, it's important that this library and its JSON have the most up-to-date, accurate and reliable data. To achieve this, the custom-built iso3166-updates
repo was created!
The iso3166-updates
repo is another open-source software package and accompanying RESTful API that pulls the latest updates and changes for any and all countries in the ISO 3166 from a variety of data sources including the ISO website itself. A script is called periodically to check for any updates/changes to the subdivisions, which are communicated via the ISO's Online Browsing Platform [4], and will then be manually incorporated into this repo. Please visit the repository home page for more info about the purpose and process of the software and API - iso3166-updates
.
The list of ISO 3166 updates was last updated on November 2024 (the last published ISO subdivision change). A log of the latest ISO 3166 updates can be seen in the UPDATES.md file.
The main API endpoint is:
The other endpoints available in the API are:
- https://iso3166-2-api.vercel.app/api/all
- https://iso3166-2-api.vercel.app/api/alpha/<input_alpha>
- https://iso3166-2-api.vercel.app/api/country_name/<input_country_name>
- https://iso3166-2-api.vercel.app/api/subdivision/<input_subdivision>
- https://iso3166-2-api.vercel.app/api/search/<input_search_name>
- https://iso3166-2-api.vercel.app/api/list_subdivisions
Six paths/endpoints are available in the API - /api/all
, /api/alpha
, /api/country_name
, /api/subdivision
, /api/search
and /api/list_subdivisions
.
-
/api
: main homepage and API documentation. -
/api/all
: get all of the ISO 3166 subdivision data for all countries. -
/api/alpha
: get all of the ISO 3166 subdivision data for 1 or more inputted ISO 3166-1 alpha-2, alpha-3 or numeric country codes, e.g./api/alpha/FR,DE,HU,ID,MA
,/api/alpha/FRA,DEU,HUN,IDN,MAR
and/api/alpha/428,504,638
. A comma separated list of multiple alpha codes can also be input. If an invalid country code is input then an error will be returned. -
/api/country_name
: get all of the ISO 3166 subdivision data for 1 or more inputted ISO 3166-1 country names, as they are commonly known in English, e.g./api/country_name/France,Moldova,Benin
. A comma separated list of country names can also be input. A closeness function is utilised so the most approximate name from the input will be used e.g. Sweden will be returned if the input is/api/country_name/Swede
. If no country is found from the closeness function or an invalid name is input then an error will be returned. Thelikeness
query string parameter can be used with this endpoint. -
/api/subdivision
: get all of the ISO 3166 subdivision data for 1 or more ISO 3166-2 subdivision codes, e.g/api/subdivision/GB-ABD
. You can also input a comma separated list of subdivision codes from the same and or different countries and the data for each will be returned e.g/api/subdivision/IE-MO,FI-17,RO-AG
. If the input subdivision code is not in the correct format then an error will be raised. Similarly if an invalid subdivision code that doesn't exist is input then an error will be raised. -
/api/search/
: get all of the ISO 3166 subdivision data for 1 or more ISO 3166-2 subdivision names that match the inputted search terms, e.g/api/search/Derry
,/api/search/Kimpala
. You can also input a comma separated list of subdivision name from the same or different countries and the data for each will be returned e.g/api/name/Paris,Frankfurt,Rimini
. A closeness function is utilised to find the matching subdivision name, if no exact name match found then the most approximate subdivisions will be returned. Some subdivisions may have the same name, in this case each subdivision and its data will be returned e.g/api/name/Saint George
(this example returns 5 subdivisions). If an invalid subdivision name that doesn't match any is input then an error will be raised. Thelikeness
andexcludeMatchScore
query string parameters can be used with this endpoint. -
/api/list_subdivisions
: get list of all the subdivision codes for all countries. You can also get the list of subdivisions from a subset of countries via their ISO 3166-1 country code.
There are three main query string parameters that can be passed through several of the endpoints of the API:
- likeness - this is a value between 1 and 100 that increases or reduces the % of similarity/likeness that the
inputted search terms have to match to the subdivision data in the subdivision code, name and local/other name attributes. This can be used with the
/api/search
and/api_country_name
endpoints. Having a higher value should return more exact and less total matches and having a lower value will return less exact but more total matches, e.g/api/search/Paris?likeness=50
,/api/country_name/Tajikist?likeness=90
(default=100). - filterAttributes - this is a list of the default supported attributes that you want to include in the output. By default all attributes will be returned but this parameter is useful if you only require a subset of attributes, e.g
api/alpha/DEU?filterAttributes=latLng,flag
,api/subdivision/PL-02?filterAttributes=localOtherName
. - excludeMatchScore - this allows you to exclude the matchScore attribute from the search results when using the
/api/search endpoint
. The match score is the % of a match each returned subdivision data object is to the search terms, with 100% being an exact match. By default the match score is returned for each object, e.g/api/search/Bucharest?excludeMatchScore=1
,/api/search/Oregon?excludeMatchScore=1
(default=0).
The API documentation and usage with all useful commands and examples to the API is available on the API.md file.
A demo of the software and API is available here.
/iso3166_2
- source code foriso3166-2
software./scripts
- scripts for the full export pipeline for the ISO 3166-2 subdivision data. -->/iso3166_2_resources
- several resource/utility and dataset files required for the full export pipeline for the ISO 3166-2 subdivision data./docs
- documentation foriso3166-2
, available on readthedocs./tests
- unit and integration tests foriso3166-2
UPDATES.md
- markdown file listing all of the additions, amendments and deletions to the ISO 3166-2 dataset (dating from 2022), exported via theiso3166-updates
software.
Any issues, bugs or enhancements can be raised via the Issues tab in the repository. If you would like to contribute any functional/feature changes to the project, please make a Pull Request.
If you have any questions, comments or suggestions, please contact amckenna41@qub.ac.uk or raise an issue in the Issues tab.
Below are some of my other custom-built repositories that relate to the ISO 3166 standard! ⚡
- iso3166-2-api: frontend RESTful API for iso3166-2.
- iso3166-updates: software and accompanying RESTful API that checks for any updates/changes to the ISO 3166-1 and ISO 3166-2 country codes and subdivision naming conventions, as per the ISO 3166 newsletter (https://www.iso.org/iso-3166-country-codes.html) and Online Browsing Platform (OBP) (https://www.iso.org/obp/ui).
- iso3166-updates-api: frontend RESTful API for iso3166-updates.
- iso3166-flag-icons: a comprehensive library of over 3500 country and regional flags from the ISO 3166-1 and ISO 3166-2 standards.
[1]: https://en.wikipedia.org/wiki/ISO_3166
[2]: https://en.wikipedia.org/wiki/ISO_3166-2
[3]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
[4]: https://www.iso.org/obp/ui/#