pycountry /

Filename Size Date modified Message
63 B
Move to py.test, update databases.
214 B
Finally an update. Adapted to the new JSON format and revamped a few things.
2.1 KB
Tagging 18.12.8
5.9 KB
Back to development: 18.12.9
24.5 KB
Added license file.
83 B
Improve manifest to find all data files (but ignore pyc).
125 B
- Updated to include fix for empty numeric codes from Debian.
6.5 KB
Remove the code and badge.
45 B
Added support for ISO 3166-2 databases.
625 B
So I heard I like virtualenv so I'm putting a virtualenv in my virtualenv!
1.1 KB
Fix buildout ... was broken for ... some reason?
347 B
Start providing a nix environment, for nix-shell based development.
2.0 KB
Update to iso-codes 4.1.
45 B
Start a sublime project.
85 B
Move to py.test, update databases.
64 B
Lets built universal wheels to express Python2/3 compatibility.
1.7 KB
Back to development: 18.12.9
372 B
* Clean up historical countries: the deleted flag is gone and there is no


pycountry provides the ISO databases for the standards:

Deleted countries
Subdivisions of countries

The package includes a copy from Debian's pkg-isocodes and makes the data accessible through a Python API.

Translation files for the various strings are included as well.

Data update policy

No changes to the data will be accepted into pycountry. This is a pure wrapper around the ISO standard using the pkg-isocodes database from Debian as is. If you need changes to the politicial situation in the world, please talk to the ISO or Debian people, not me.

Donations / Monetary Support

This is a small project that I maintain in my personal time. I am not interested in personal financial gain. However, if you would like to support the project then I would love if you would donate to Feminist Frequency instead. Also, let the world know you did so, so that others can follow your path.


The code lives in a bitbucket Mercurial repository, and issues must be reported in project bugtracker.

Countries (ISO 3166)

Countries are accessible through a database object that is already configured upon import of pycountry and works as an iterable:

>>> import pycountry
>>> len(pycountry.countries)
>>> list(pycountry.countries)[0]
Country(alpha_2='AF', alpha_3='AFG', name='Afghanistan', numeric='004', official_name='Islamic Republic of Afghanistan')

Specific countries can be looked up by their various codes and provide the information included in the standard as attributes:

>>> germany = pycountry.countries.get(alpha_2='DE')
>>> germany
Country(alpha_2='DE', alpha_3='DEU', name='Germany', numeric='276', official_name='Federal Republic of Germany')
>>> germany.alpha_2
>>> germany.alpha_3
>>> germany.numeric
>>> germany.official_name
'Federal Republic of Germany'

The historic_countries database contains former countries that have been removed from the standard and are now included in ISO 3166-3, excluding existing ones:

>>> ussr = pycountry.historic_countries.get(alpha_3='SUN')
>>> ussr
Country(alpha_3='SUN', alpha_4='SUHH', withdrawal_date='1992-08-30', name='USSR, Union of Soviet Socialist Republics', numeric='810')
>>> ussr.alpha_4
>>> ussr.alpha_3
'USSR, Union of Soviet Socialist Republics'
>>> ussr.withdrawal_date

Country subdivisions (ISO 3166-2)

The country subdivisions are a little more complex than the countries itself because they provide a nested and typed structure.

All subdivisons can be accessed directly:

>>> len(pycountry.subdivisions)
>>> list(pycountry.subdivisions)[0]
Subdivision(code='AD-07', country_code='AD', name='Andorra la Vella', parent_code=None, type='Parish')

Subdivisions can be accessed using their unique code and provide at least their code, name and type:

>>> de_st = pycountry.subdivisions.get(code='DE-ST')
>>> de_st.code
>>> de_st.type
Country(alpha_2='DE', alpha_3='DEU', name='Germany', numeric='276', official_name='Federal Republic of Germany')

Some subdivisions specify another subdivision as a parent:

>>> al_br = pycountry.subdivisions.get(code='AL-BU')
>>> al_br.code
>>> al_br.type
>>> al_br.parent_code
>>> al_br.parent
Subdivision(code='AL-09', country_code='AL', name='Dib\xebr', parent_code=None, type='County')

The divisions of a single country can be queried using the country_code index:

>>> len(pycountry.subdivisions.get(country_code='DE'))
>>> len(pycountry.subdivisions.get(country_code='US'))

Scripts (ISO 15924)

Scripts are available from a database similar to the countries:

>>> len(pycountry.scripts)
>>> list(pycountry.scripts)[0]
Script(alpha_4='Afak', name='Afaka', numeric='439')
>>> latin = pycountry.scripts.get(name='Latin')
>>> latin
Script(alpha_4='Latn', name='Latin', numeric='215')
>>> latin.alpha4
>>> latin.numeric

Currencies (ISO 4217)

The currencies database is, again, similar to the ones before:

>>> len(pycountry.currencies)
>>> list(pycountry.currencies)[0]
Currency(alpha_3='AED', name='UAE Dirham', numeric='784')
>>> argentine_peso = pycountry.currencies.get(alpha_3='ARS')
>>> argentine_peso
Currency(alpha_3='ARS', name='Argentine Peso', numeric='032')
>>> argentine_peso.alpha_3
'Argentine Peso'
>>> argentine_peso.numeric

Languages (ISO 639-3)

The languages database is similar too:

>>> len(pycountry.languages)
>>> list(pycountry.languages)[0]
Language(alpha_3='aaa', name='Ghotuo', scope='I', type='L')
>>> aragonese = pycountry.languages.get(alpha_2='an')
>>> aragonese.alpha_2
>>> aragonese.alpha_3
>>> bengali = pycountry.languages.get(alpha_2='bn')
>>> bengali.common_name


Locales are available in the pycountry.LOCALES_DIR subdirectory of this package. The translation domains are called isoXXX according to the standard they provide translations for. The directory is structured in a way compatible to Python's gettext module.

Here is an example translating language names:

>>> import gettext
>>> german = gettext.translation('iso3166', pycountry.LOCALES_DIR,
...                              languages=['de'])
>>> german.install()
>>> _('Germany')


For each database (countries, languages, scripts, etc.), you can also look up entities case insensitively without knowing which key the value may match. For example:

>>> pycountry.countries.lookup('de')
<pycountry.db.Country object at 0x...>

The search ends with the first match, which is returned.