Changelog
v1.8.1/v.1.8.2 - February 2026
Added
Updated accuracy of all latLng attributes for all subdivisions, using the centroid of the subdivision as the new value
Added logo to the main readme
Added /spec & /openapi.yml endpoints on API, added unit tests
Added /random endpoint on API that returns a random subdivision from the >5000 available, added unit tests
Added additional unit and integration tests for each module
Added a output message in the custom_subdivision when adding one to ensure the user keeps track of the new subdivision accurately
Created new history module, separating the iso3166-updates history functionalities into separate module - added unit tests
Added remove_attribute function within main iso3166-2.py module, it allows for you to remove from memory and from the dataset any unneeded attributes, saving a load of memory
For some of the modules in /scripts that require an API key, this key can also be put into a .env file that the module can look for
Added additional and more informative type hints to some of the functions
Added anomaly detection function that uses openai api to generate a CSV that outputs any anomalies or errors found in the iso3166-2.json object
Added integration tests that validate that each latLng value for each subdivision falls within the boundary of the country
Added Geo module used for getting everything latLng related per subdivision including centroid, bounding box and the relevant API calls
For the Geo module, created a cache file (iso3166_2_resources/geo_cache.csv) that stores all of the exported geographical related data per subdivision that is imported during execution, rather than having to make API calls each time
Added additional info to the __repr__ and __str__ functions in iso3166_2
Added wikidata package to /scripts dependencies
Added individual Subdivision data class to iso3166_2 package
Added self.alpha2 attribute in iso3166-2 package that lists the ISO 3166-1 country codes
Changed
Implemented more accurate method of getting lat/long via openstreetmap instead of Google Maps API
Split several of the export functionalities in /scripts into their own modules for readability and extensibility
In many of the test modules, split up the test class functions into integration and unit tests
Updated history attribute within each subdivision such that it displays the history object as is in the iso3166-updates software
Removed the extract_lat_lng parameter - since we’re using the OSM to get the
When exporting the data via the export pipeline. If save_each_iteration is set to True, only the JSON of the data will be exported, not the XML and CSV as well
Updated github workflow, including adding concurrency and caching
Changed any references to the python-iso3166 software to pycountry, as pycountry is more updated and maintained
Removed GB-EAW GB-GBN and GB-UKM from dataset, these were previously included as they were in the remark section of GB’s ISO page but not included in other ISO 3166 lists
In main export function, removed skip latLng functionality that skips the exporting of the latLng attribute - the attribute data is now cached in a separate file so no need to be skipped
Fixed
Fixed accuracy of some of the latLng attribute values for some subdivisions, using the OSM as a data source rather than the previous Google Maps API
v1.8.0 - September 2025
Added
Added new file saving functionality for custom_subdivisions function
Added API tests to /tests dir
Added Vercel webhook to the workflow, this redeploys the API vercel app once new version of the software released from this repo
In script dir added a metadata script that exports a plethora of useful metadata about the software and data object
Added functionality to the iso3166-2 main software such that the subdivision_codes() and subdivision_names() functions can be called through the subscripted country code object
Added optional ‘archive’ parameter to update_subdivisions() function that can be set to True/False and will archive the existing iso3166-2 object before any changes are made
Added CSV and XML of iso3166-2 dataset to iso3166_2_resources dir on repo
When exporting the individual data to JSON, CSV and XML, in the function you can now import an already exported JSON file to just export the CSV and XML files
Created function that allows you to combines multiple exports into one file, use case is for when alpha_codes_range was used to export a batch of export data and you need to combine into one master file
Added unit test that checks that each flag url is valid
When exporting the ISO 3166-2 data, setting rest_countries_keys=* will export all of them
Changed
Updated MANIFEST.in file to align with updated project structure
Fixed deprecated upload-artefact error in github workflow
Main export function name changed in get_iso3166_2 as it was very similar to the export data function in utils
Removed filter_attributes functionality from utils export function
Updated all references of iso3166-flag-icons to iso3166-flags to reflect updated repository name - including for each individual flag url in object
Removed filter_attributes functionality from update_subdivisions function
Changed export script name from get_iso3166_2 to export_iso3166_2
Removed any additional flags from the iso3166-1-flags dataset that aren’t strictly in the ISO 3166-1, including eu, arab league, UN and XX flags
Updated the workflow such that unit tests for specific modules are only run when changes are made to those modules rather than all tests being run. If workflow dispatch is set then all tests will be run
Switched from using unittest framework to pytest as the tests were being run twice
Fixed
RestCountries keys error fixed where the keys were getting added to the same column in the csv output
Fixed column export for csv
Ensured all empty attributes “” are converted to null
Several subdivision names and local/other names still contained * the † in them
requests dependency missing in pyproject
Fixed small vulnerability with try/except in metadata export module
Fixed the bandit & package calls in workflow, passing in specific directories
v1.7.0 - 1.7.2 - July 2025
Added
Add list of cities for each subdivision using the country-states-city API
Added __version__ attribute to Subdivisions() class
Local names attribute added with up-to-date accurate names
For each subdivision’s local name in the localName attribute, if the attribute isn’t null then add the ISO 639 language code in brackets after the value. If there are multiple local names, separate via comma
Function added to ISO3166_2() class that checks for the latest version of the ISO3166-2 object, returning the differences of the current version
When adding a custom subdivision via its respective function, user can also add custom attributes to it e.g population, area etc
In Subdivisions class, you can now create an instance of the class but exclude some of the default attributes returned per subdivisions
Added unit tests, docs updates and examples in readme’s about accessing multiple country’s subdivision data via an instance of the object directly
For the localOtherName attribute, for non-latin alphabet subdivision, added the phonetic transcriptions e.g for Chinese subdivisions, Pinyin chinese is included for each subdivision
Added filter query string parameter to API, allowing for specific attributes for the subdivisions to be filtered in the API GET request e.g “?filter=name,type” etc
Added filter parameter to search function in software, allowing you to search for a subdivision, returning only a subset of desired attributes
Added new unit tests for the filter query string parameter
In add_local_names function, new parameter called remove_duplicate_translations added. When set to 1, any values in localOtherName column that match the same official subdivision name in the name column, remove the specific local/other name. For example, CG-7: official name in French is Likouala which is the same as it is translated in English, DO-38: official name in Spanish is Enriquillo which is similar to its English translation Enriquillo
When importing the local names csv, an error is raised if no language code is specified for the local/other name
Additional unit tests added for new local/other name functionality including tests that validate the language code
In get script, prior to exporting a message is printed out which includes all the attributes to be exported
Added parameter to local names function where you can limit the number of local/other names per subdivision attribute. This is useful for some subdivisions’s which have up to 6 or 7 translations/local variants etc
Added additional unit tests for subdivision_updates.csv
Added extra validation on subdivision_updates.csv, ensuring alpha codes, subdivision codes and date format are the valid format etc
The search functionality in the Python package now allows you to include a subset of subdivision attributes via the filter_attributes function parameter
The search functionality in the Python package now allows you to search via the localOtherName attribute as well as the default name attribute. By default only the name attribute is searched over
Language lookup custom script which creates a Language class and generates an output file of each language used in the local/other names file, including its code and name
Language lookup csv which is a custom exported file of language codes and their associated names
Unit tests for language lookup functionality
Added utilities module which contains several functions that are used across the project, rather than replicating the functions in multiple modules
requirements.txt added to scripts directory to outline the full list of packages for export pipeline
Add __str__ and __repr__ functions to language lookup class in export pipeline, added relevant unit tests
Added get_alpha_codes_list & export_iso3166_2_data utility functions, cleaning up the main function - relevant unit tests added to test_utils
Added patching to unit tests such that system outputs/print statements are not displayed from modules when running tests
Added delete language object functionality to language lookup table
Added user agent functionality to language lookup script
In language lookup export function, you can now put in custom language code to export
In update_subdivisions module and function, you can now add custom attributes to a subdivision via the custom_attributes parameter
Added logic to ensure the custom order of attributes in exported iso3166-2 object is maintained
In extract script, optional proxy functionality added to requests.get functions to help avoid 429 errors and timeout errors
In custom subdivision function is sw, you can now pass in an object of updates attributes
Added exclude_match_score attribute to search function that allows you to include/exclude the % match the subdivision names are to the input search terms
Changed
In convert_to_alpha2 function that converts a alpha-3 or numeric code into alpha-2, if a alpha-2 code was input it returns None instead of the same input alpha-2
Some spanish subdivision names had a “*” at the end of their name e.g ES-A, ES-NA, which has now been removed
For filter query string param, passing in no value to it would throw an error, now it just returns all data as is
Updated all 2 letter ISO 639 language codes in local/other names csv into their ISO 639-2/3 counterparts
When including historical updates data when exporting for each subdivision in the get_script, the language codes within the localOtherName column are removed
Fixed error where only the first local/other name for a specific row is being imported
Convert to alpha_2 code function changed such that if an invalid code is input it is returned from the function and an error raised instead of just returning None/null
In custom_subdivision function, the original subdivision data/JSON was being reimported. Now the main self.all attribute is used
Several rows (adds, amends, deletes) removed from subdivision_updates.csv as they are implemented in base object now
Error with None values in subdivision_updates.csv not being interpreted as None
Fixed error with adding rest country data to subdivisions
Fixed
In the update_subdivisions function when editing a subdivision and its actual subdivision code, the flag attribute may have erroneous or null data
v1.6.1 - June 2024
Added
list_subdivisions endpoint added to API that returns list of all subdivision codes per country
Unit tests for flag_url function in update_subdivisions script
Separate function for extracting and parsing data attributes from RestCountries API
Added raise_for_status error catcher for requests library
Changed
Rotate user agent headers for any scripts using requests.get
Contributing page on docs updated
Fixed
Error in request URL for RestCountries API in update_subdivisions script
Raise TypeError if invalid data type input to export_iso3166_2 function rather than system crashing
When getting the coordinates (latitude/longitude) per subdivision, a more granular and accurate response is ensured by appending the country name to the subdivision name when searching via the Google Maps API
v1.6.0 - June 2024
Added
New dataset object exported with flagUrl attribute now flag
Added functionality for adding additional country-level attributes per subdivision via the RestCountries API
Added functionality for excluding some of the default attributes that are exported for every subdivision by default
Added functionality for get_iso3166_2 script where you can export all data starting from a specified ISO 3166-1 alpha code alphabetically
Parameter typing for each function
Added more info to the error messages
Code coverage
Added additional unit tests for CSV export of ISO 3166-2 dataset from get_iso3166_2 script
Added unit tests for update_subdivisions functionality
Added export_csv parameter to get_iso3166_2 script to allow for optional export to CSV, JSON exported by default
Added iso3166 object filepath parameter to the ISO3166_2() class that allows for custom object to be imported on class instantiation
Changed
flagUrl attribute changed to flag in dataset
Moved functionality for getting subdivision flag data into its own function in update_subdivisions.py script
When exporting data using get_iso3166_2 script, export to CSV by default
update_subdivisions script can be called by itself from the cmd line/terminal, passing in the required parameters
Added flag/parameter to custom_subdivisions function where if set you can create a hard copy of the existing iso3166-2.json object so that you aren’t directly adding/amending/deleting a subdivision from the object
Sort rows in iso3166_2_updates/subdivision_updates.csv by date (newest first) rather than by alpha-2 country code
Update package description
Updated unit tests to reflect above changes and new features
Split up jobs in build workflows into separate sections
Added more info for each functionality with additional examples in the software and API documentation
Upgrade checkout action in workflow from v3 to v4
Raise error in update_subdivisions script when trying to delete a subdivision that doesn’t exist
In unit tests, exclude latLng attribute so gmaps API isn’t called when running
When adding a custom subdivision via the respective function, the “name” and “type” attributes are no longer explicitly required
Fixed
In the update_subdivisions function when editing a subdivision and its actual subdivision code, the flag attribute may have erroneous or null data
In the update_subdivisions function you can now put in the full subdivision code or just the right hand side of the code into the subdivision_code parameter
In the update_subdivisions function when amending an existing subdivision’s code, the current flag URL attribute value points to the original flag URL, check on repo if flag with new subdivision code exists, otherwise keep the value to the original
In the update_subdivisions function when amending an existing subdivision’s code, error now raised when the new subdivision code’s country code does not match the original
If a custom subdivision object is input via its respective function, latLng attribute is set to 3d.p
Fixed syntax of some function parameters that can take multiple data types
Fixed parameter typing syntax for some function parameters that can be multiple data types
Error when adding a new subdivision, now will raise an error if the input parent code is invalid/not a country subdivision
In get_flag_url function in update_subdivision script, you can pass in the full subdivision code or just the RHS of it
v1.5.4 - March 2024
Added
Add a likeness score parameter to the search functionality such that it will return one or more subdivisions that match according to the percentage of likeness
Added custom_subdivision function where user can add a custom subdivision to the iso3166-2 object
Add UPDATES.md file that outlines all recent subdivision changes to the ISO 3166-2 data
Changed
Changed data encapsulation for object, with the dataset now accessible after creating an instance of the ISO3166_2 class
Change search functionality algorithm from difflib to thefuzz libary
Change setup.py to pyproject.toml
Update unit tests to reflect changes made to the software such as likeness score and searching method etc
Change iso3166_2_updates directory to iso316_2_updates
Fixed
Incorrect subdivision data returning when searching for a subdivision using its name when its name had a comma in it
GitHub repo badges not displaying correctly
v1.4.0 - December 2023
Added
readthedocs documentation added
Search for a particular subdivision via its subdivision name, finding the closest match using difflib libary
Added dateIssued and notes columns to subdivision_updates.csv, sort by country code and then by dateIssued
tqdm progress loop added to get_iso3166_2 script
Changed
Software package description updated
Changed software license to MIT
Remove subdivision_parent_codes function that returned this list of parent codes per subdivision
v1.3.0 - December 2023
Added
Added subdivision_updates.csv that lists rows of updates made to the ISO 3166-2 subdivision data
Added local_names.csv file that lists the names of each subdivision in their local languages
lat_lng attribute added for each subdivision using the googlemaps API, set to 3d.p
Changed
When running unit tests on iso3166-2.json object, create a backup/archive of object before running tests
Fixed
Subdivision codes not sorting alphabetically in output
v1.2.0 and earlier
Added
Initial software release
Initial API release
Added any missing iso3166-2 subdivision data to object that may have been missing from initial export
Initial attributes include: country code, subdivision code, parent code, type and flag URL
Created custom-built iso3166-updates software used to track all updates made by the ISO to the ISO 3166