# Isocountry
<p align="center">
<a href="https://github.com/yezz123/isocountry/actions/workflows/ci.yaml" target="_blank">
<img src="https://github.com/yezz123/isocountry/actions/workflows/ci.yaml/badge.svg" alt="CI">
</a>
<a href="https://pypi.org/project/isocountry" target="_blank">
<img src="https://img.shields.io/pypi/v/isocountry?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
<a href="https://codecov.io/gh/yezz123/isocountry">
<img src="https://codecov.io/gh/yezz123/isocountry/branch/main/graph/badge.svg"/>
</a>
</p>
## ⛔️⛔️ pycountry Hard Fork
This is a hard fork of the `pycountry` library, which we've undertaken due to the lack of active maintenance in the original repository. The purpose of this fork is to ensure the continued functionality and support of `pycountry` within the [Pydantic-extra-types](https://github.com/pydantic/pydantic-extra-types) project. Our goals include maintaining, bug fixing, enhancing, and seamlessly integrating this fork into the Pydantic ecosystem. Your contributions and support are appreciated as we strive to keep this vital resource alive and thriving.
## Features
Isocountry provides the ISO databases for the standards:
* [639-3](https://en.wikipedia.org/wiki/ISO_639-3) - Languages
* [3166](https://en.wikipedia.org/wiki/ISO_3166) - Countries
* [3166-3](https://en.wikipedia.org/wiki/ISO_3166-3) - Deleted countries
* [3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) - Subdivisions of countries
* [4217](https://en.wikipedia.org/wiki/ISO_4217) - Currencies
* [15924](https://en.wikipedia.org/wiki/ISO_15924) - Scripts
The package includes a copy from Debian's [pkg-isocodes](https://salsa.debian.org/iso-codes-team/iso-codes) 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 isocountry. This is a pure wrapper
around the ISO standard using the `pkg-isocodes` database from Debian *as is*.
If you need changes to the political situation in the world, please talk to
the ISO or Debian people, not me.
#### Countries (ISO 3166-1)
Countries are accessible through a database object that is already configured
upon import of isocountry and works as an iterable:
```py
>>> import isocountry
>>> len(isocountry.countries)
249
>>> list(isocountry.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:
```py
>>> germany = isocountry.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
'DE'
>>> germany.alpha_3
'DEU'
>>> germany.numeric
'276'
>>> germany.name
'Germany'
>>> germany.official_name
'Federal Republic of Germany'
```
There's also a "fuzzy" search to help people discover "proper" countries for
names that might only actually be subdivisions. The fuzziness also includes
normalizing unicode accents. There's also a bit of prioritization included
to prefer matches on country names before subdivision names and have countries
with more matches be listed before ones with fewer matches:
```py
>>> isocountry.countries.search_fuzzy('England')
[Country(alpha_2='GB', alpha_3='GBR', name='United Kingdom', numeric='826', official_name='United Kingdom of Great Britain and Northern Ireland')]
>>> isocountry.countries.search_fuzzy('Cote')
[Country(alpha_2='CI', alpha_3='CIV', name="Côte d'Ivoire", numeric='384', official_name="Republic of Côte d'Ivoire"),
Country(alpha_2='FR', alpha_3='FRA', name='France', numeric='250', official_name='French Republic'),
Country(alpha_2='HN', alpha_3='HND', name='Honduras', numeric='340', official_name='Republic of Honduras')]
```
#### Historic Countries (ISO 3166-3)
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:
```py
>>> ussr = isocountry.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
'SUHH'
>>> ussr.alpha_3
'SUN'
>>> ussr.name
'USSR, Union of Soviet Socialist Republics'
>>> ussr.withdrawal_date
'1992-08-30'
```
#### 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:
```py
>>> len(isocountry.subdivisions)
4847
>>> list(isocountry.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:
```py
>>> de_st = isocountry.subdivisions.get(code='DE-ST')
>>> de_st.code
'DE-ST'
>>> de_st.name
'Sachsen-Anhalt'
>>> de_st.type
'State'
>>> de_st.country
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:
```py
>>> al_br = isocountry.subdivisions.get(code='AL-BU')
>>> al_br.code
'AL-BU'
>>> al_br.name
'Bulqiz\xeb'
>>> al_br.type
'District'
>>> al_br.parent_code
'AL-09'
>>> al_br.parent
Subdivision(code='AL-09', country_code='AL', name='Dib\xebr', parent_code=None, type='County')
>>> al_br.parent.name
'Dib\xebr'
```
The divisions of a single country can be queried using the country_code index:
```py
>>> len(isocountry.subdivisions.get(country_code='DE'))
16
>>> len(isocountry.subdivisions.get(country_code='US'))
57
```
#### Scripts (ISO 15924)
Scripts are available from a database similar to the countries:
```py
>>> len(isocountry.scripts)
169
>>> list(isocountry.scripts)[0]
Script(alpha_4='Afak', name='Afaka', numeric='439')
>>> latin = isocountry.scripts.get(name='Latin')
>>> latin
Script(alpha_4='Latn', name='Latin', numeric='215')
>>> latin.alpha4
'Latn'
>>> latin.name
'Latin'
>>> latin.numeric
'215'
```
#### Currencies (ISO 4217)
The currencies database is, again, similar to the ones before:
```py
>>> len(isocountry.currencies)
182
>>> list(isocountry.currencies)[0]
Currency(alpha_3='AED', name='UAE Dirham', numeric='784')
>>> argentine_peso = isocountry.currencies.get(alpha_3='ARS')
>>> argentine_peso
Currency(alpha_3='ARS', name='Argentine Peso', numeric='032')
>>> argentine_peso.alpha_3
'ARS'
>>> argentine_peso.name
'Argentine Peso'
>>> argentine_peso.numeric
'032'
```
#### Languages (ISO 639-3)
The languages database is similar too:
```py
>>> len(isocountry.languages)
7874
>>> list(isocountry.languages)[0]
Language(alpha_3='aaa', name='Ghotuo', scope='I', type='L')
>>> aragonese = isocountry.languages.get(alpha_2='an')
>>> aragonese.alpha_2
'an'
>>> aragonese.alpha_3
'arg'
>>> aragonese.name
'Aragonese'
>>> bengali = isocountry.languages.get(alpha_2='bn')
>>> bengali.name
'Bengali'
>>> bengali.common_name
'Bangla'
```
#### Locales
Locales are available in the `isocountry.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:
```py
>>> import gettext
>>> german = gettext.translation('iso3166-1', isocountry.LOCALES_DIR,
... languages=['de'])
>>> german.install()
>>> _('Germany')
'Deutschland'
```
#### Lookups
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:
```py
>>> isocountry.countries.lookup('de')
(isocountry.db.Country object at 0x...>
```
The search ends with the first match, which is returned.
## Development 🚧
### Setup environment 📦
You should create a virtual environment and activate it:
```bash
python -m venv venv/
```
```bash
source venv/bin/activate
```
And then install the development dependencies:
```bash
# Install dependencies
pip install -e .[test,lint]
```
### Run tests 🌝
You can run all the tests with:
```bash
bash scripts/tests.sh
```
### Format the code 🍂
Execute the following command to apply `pre-commit` formatting:
```bash
bash scripts/format.sh
```
Raw data
{
"_id": null,
"home_page": "",
"name": "isocountry",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "15924,3166,3166-2,4217,639,country,currency,iso,language,subdivision",
"author": "",
"author_email": "Yasser Tahiri <hello@yezz.me>, Christian Theune <ct@flyingcircus.io>",
"download_url": "https://files.pythonhosted.org/packages/fd/f8/2624841951deab2a010afa0ef1fa4cad7a7dce8cb83a50e89d3f9e683230/isocountry-23.2.0.tar.gz",
"platform": null,
"description": "# Isocountry\n\n<p align=\"center\">\n<a href=\"https://github.com/yezz123/isocountry/actions/workflows/ci.yaml\" target=\"_blank\">\n <img src=\"https://github.com/yezz123/isocountry/actions/workflows/ci.yaml/badge.svg\" alt=\"CI\">\n</a>\n<a href=\"https://pypi.org/project/isocountry\" target=\"_blank\">\n <img src=\"https://img.shields.io/pypi/v/isocountry?color=%2334D058&label=pypi%20package\" alt=\"Package version\">\n</a>\n<a href=\"https://codecov.io/gh/yezz123/isocountry\">\n <img src=\"https://codecov.io/gh/yezz123/isocountry/branch/main/graph/badge.svg\"/>\n</a>\n</p>\n\n\n## \u26d4\ufe0f\u26d4\ufe0f pycountry Hard Fork\n\nThis is a hard fork of the `pycountry` library, which we've undertaken due to the lack of active maintenance in the original repository. The purpose of this fork is to ensure the continued functionality and support of `pycountry` within the [Pydantic-extra-types](https://github.com/pydantic/pydantic-extra-types) project. Our goals include maintaining, bug fixing, enhancing, and seamlessly integrating this fork into the Pydantic ecosystem. Your contributions and support are appreciated as we strive to keep this vital resource alive and thriving.\n\n## Features\n\nIsocountry provides the ISO databases for the standards:\n\n* [639-3](https://en.wikipedia.org/wiki/ISO_639-3) - Languages\n* [3166](https://en.wikipedia.org/wiki/ISO_3166) - Countries\n* [3166-3](https://en.wikipedia.org/wiki/ISO_3166-3) - Deleted countries\n* [3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) - Subdivisions of countries\n* [4217](https://en.wikipedia.org/wiki/ISO_4217) - Currencies\n* [15924](https://en.wikipedia.org/wiki/ISO_15924) - Scripts\n\nThe package includes a copy from Debian's [pkg-isocodes](https://salsa.debian.org/iso-codes-team/iso-codes) and makes the data\naccessible through a Python API.\n\nTranslation files for the various strings are included as well.\n\n### Data update policy\n\nNo changes to the data will be accepted into isocountry. This is a pure wrapper\naround the ISO standard using the `pkg-isocodes` database from Debian *as is*.\nIf you need changes to the political situation in the world, please talk to\nthe ISO or Debian people, not me.\n\n#### Countries (ISO 3166-1)\n\nCountries are accessible through a database object that is already configured\nupon import of isocountry and works as an iterable:\n\n```py\n\n >>> import isocountry\n >>> len(isocountry.countries)\n 249\n >>> list(isocountry.countries)[0]\n Country(alpha_2='AF', alpha_3='AFG', name='Afghanistan', numeric='004', official_name='Islamic Republic of Afghanistan')\n```\n\nSpecific countries can be looked up by their various codes and provide the\ninformation included in the standard as attributes:\n\n```py\n\n >>> germany = isocountry.countries.get(alpha_2='DE')\n >>> germany\n Country(alpha_2='DE', alpha_3='DEU', name='Germany', numeric='276', official_name='Federal Republic of Germany')\n >>> germany.alpha_2\n 'DE'\n >>> germany.alpha_3\n 'DEU'\n >>> germany.numeric\n '276'\n >>> germany.name\n 'Germany'\n >>> germany.official_name\n 'Federal Republic of Germany'\n```\n\nThere's also a \"fuzzy\" search to help people discover \"proper\" countries for\nnames that might only actually be subdivisions. The fuzziness also includes\nnormalizing unicode accents. There's also a bit of prioritization included\nto prefer matches on country names before subdivision names and have countries\nwith more matches be listed before ones with fewer matches:\n\n```py\n >>> isocountry.countries.search_fuzzy('England')\n [Country(alpha_2='GB', alpha_3='GBR', name='United Kingdom', numeric='826', official_name='United Kingdom of Great Britain and Northern Ireland')]\n\n >>> isocountry.countries.search_fuzzy('Cote')\n [Country(alpha_2='CI', alpha_3='CIV', name=\"C\u00f4te d'Ivoire\", numeric='384', official_name=\"Republic of C\u00f4te d'Ivoire\"),\n Country(alpha_2='FR', alpha_3='FRA', name='France', numeric='250', official_name='French Republic'),\n Country(alpha_2='HN', alpha_3='HND', name='Honduras', numeric='340', official_name='Republic of Honduras')]\n```\n\n#### Historic Countries (ISO 3166-3)\n\nThe `historic_countries` database contains former countries that have been\nremoved from the standard and are now included in ISO 3166-3, excluding\nexisting ones:\n\n```py\n\n >>> ussr = isocountry.historic_countries.get(alpha_3='SUN')\n >>> ussr\n Country(alpha_3='SUN', alpha_4='SUHH', withdrawal_date='1992-08-30', name='USSR, Union of Soviet Socialist Republics', numeric='810')\n >>> ussr.alpha_4\n 'SUHH'\n >>> ussr.alpha_3\n 'SUN'\n >>> ussr.name\n 'USSR, Union of Soviet Socialist Republics'\n >>> ussr.withdrawal_date\n '1992-08-30'\n```\n\n#### Country subdivisions (ISO 3166-2)\n\nThe country subdivisions are a little more complex than the countries itself\nbecause they provide a nested and typed structure.\n\nAll subdivisons can be accessed directly:\n\n```py\n >>> len(isocountry.subdivisions)\n 4847\n >>> list(isocountry.subdivisions)[0]\n Subdivision(code='AD-07', country_code='AD', name='Andorra la Vella', parent_code=None, type='Parish')\n```\n\nSubdivisions can be accessed using their unique code and provide at least\ntheir code, name and type:\n\n```py\n >>> de_st = isocountry.subdivisions.get(code='DE-ST')\n >>> de_st.code\n 'DE-ST'\n >>> de_st.name\n 'Sachsen-Anhalt'\n >>> de_st.type\n 'State'\n >>> de_st.country\n Country(alpha_2='DE', alpha_3='DEU', name='Germany', numeric='276', official_name='Federal Republic of Germany')\n```\n\nSome subdivisions specify another subdivision as a parent:\n\n```py\n >>> al_br = isocountry.subdivisions.get(code='AL-BU')\n >>> al_br.code\n 'AL-BU'\n >>> al_br.name\n 'Bulqiz\\xeb'\n >>> al_br.type\n 'District'\n >>> al_br.parent_code\n 'AL-09'\n >>> al_br.parent\n Subdivision(code='AL-09', country_code='AL', name='Dib\\xebr', parent_code=None, type='County')\n >>> al_br.parent.name\n 'Dib\\xebr'\n```\n\nThe divisions of a single country can be queried using the country_code index:\n\n```py\n >>> len(isocountry.subdivisions.get(country_code='DE'))\n 16\n\n >>> len(isocountry.subdivisions.get(country_code='US'))\n 57\n```\n\n#### Scripts (ISO 15924)\n\nScripts are available from a database similar to the countries:\n\n```py\n >>> len(isocountry.scripts)\n 169\n >>> list(isocountry.scripts)[0]\n Script(alpha_4='Afak', name='Afaka', numeric='439')\n\n >>> latin = isocountry.scripts.get(name='Latin')\n >>> latin\n Script(alpha_4='Latn', name='Latin', numeric='215')\n >>> latin.alpha4\n 'Latn'\n >>> latin.name\n 'Latin'\n >>> latin.numeric\n '215'\n```\n\n#### Currencies (ISO 4217)\n\nThe currencies database is, again, similar to the ones before:\n\n```py\n >>> len(isocountry.currencies)\n 182\n >>> list(isocountry.currencies)[0]\n Currency(alpha_3='AED', name='UAE Dirham', numeric='784')\n >>> argentine_peso = isocountry.currencies.get(alpha_3='ARS')\n >>> argentine_peso\n Currency(alpha_3='ARS', name='Argentine Peso', numeric='032')\n >>> argentine_peso.alpha_3\n 'ARS'\n >>> argentine_peso.name\n 'Argentine Peso'\n >>> argentine_peso.numeric\n '032'\n```\n\n#### Languages (ISO 639-3)\n\nThe languages database is similar too:\n\n```py\n >>> len(isocountry.languages)\n 7874\n >>> list(isocountry.languages)[0]\n Language(alpha_3='aaa', name='Ghotuo', scope='I', type='L')\n\n >>> aragonese = isocountry.languages.get(alpha_2='an')\n >>> aragonese.alpha_2\n 'an'\n >>> aragonese.alpha_3\n 'arg'\n >>> aragonese.name\n 'Aragonese'\n\n >>> bengali = isocountry.languages.get(alpha_2='bn')\n >>> bengali.name\n 'Bengali'\n >>> bengali.common_name\n 'Bangla'\n```\n\n#### Locales\n\nLocales are available in the `isocountry.LOCALES_DIR` subdirectory of this\npackage. The translation domains are called `isoXXX` according to the standard\nthey provide translations for. The directory is structured in a way compatible\nto Python's gettext module.\n\nHere is an example translating language names:\n\n```py\n >>> import gettext\n >>> german = gettext.translation('iso3166-1', isocountry.LOCALES_DIR,\n ... languages=['de'])\n >>> german.install()\n >>> _('Germany')\n 'Deutschland'\n```\n\n#### Lookups\n\nFor each database (countries, languages, scripts, etc.), you can also look up\nentities case insensitively without knowing which key the value may match. For\nexample:\n\n```py\n >>> isocountry.countries.lookup('de')\n (isocountry.db.Country object at 0x...>\n```\n\nThe search ends with the first match, which is returned.\n\n## Development \ud83d\udea7\n\n### Setup environment \ud83d\udce6\n\nYou should create a virtual environment and activate it:\n\n```bash\npython -m venv venv/\n```\n\n```bash\nsource venv/bin/activate\n```\n\nAnd then install the development dependencies:\n\n```bash\n# Install dependencies\npip install -e .[test,lint]\n```\n\n### Run tests \ud83c\udf1d\n\nYou can run all the tests with:\n\n```bash\nbash scripts/tests.sh\n```\n\n### Format the code \ud83c\udf42\n\nExecute the following command to apply `pre-commit` formatting:\n\n```bash\nbash scripts/format.sh\n```\n",
"bugtrack_url": null,
"license": "",
"summary": "ISO country, subdivision, language, currency and script definitions and their translations",
"version": "23.2.0",
"project_urls": {
"Documentation": "https://github.com/yezz123/isocountry/blob/main/README.md",
"Homepage": "https://github.com/yezz123/isocountry"
},
"split_keywords": [
"15924",
"3166",
"3166-2",
"4217",
"639",
"country",
"currency",
"iso",
"language",
"subdivision"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "70b70ba5c3c4ad7b519efef3482930ba7f38a362769f6e1df76dcc40ae06029e",
"md5": "b078834f7668cbaad8de609d04fae8dd",
"sha256": "b286d423844ec864985f5bb841331a4ddfa5d8b1f386f855098c390232ed13b2"
},
"downloads": -1,
"filename": "isocountry-23.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b078834f7668cbaad8de609d04fae8dd",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 6209639,
"upload_time": "2023-10-22T22:00:19",
"upload_time_iso_8601": "2023-10-22T22:00:19.641512Z",
"url": "https://files.pythonhosted.org/packages/70/b7/0ba5c3c4ad7b519efef3482930ba7f38a362769f6e1df76dcc40ae06029e/isocountry-23.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "fdf82624841951deab2a010afa0ef1fa4cad7a7dce8cb83a50e89d3f9e683230",
"md5": "155330ee948f460781a80e74ed9ea99b",
"sha256": "ccf189a1d75e8793a0335c1d0ab74bca6e6a9d00691c083a17e6144f7f8c20d9"
},
"downloads": -1,
"filename": "isocountry-23.2.0.tar.gz",
"has_sig": false,
"md5_digest": "155330ee948f460781a80e74ed9ea99b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 5876749,
"upload_time": "2023-10-22T22:00:22",
"upload_time_iso_8601": "2023-10-22T22:00:22.235547Z",
"url": "https://files.pythonhosted.org/packages/fd/f8/2624841951deab2a010afa0ef1fa4cad7a7dce8cb83a50e89d3f9e683230/isocountry-23.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-22 22:00:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "yezz123",
"github_project": "isocountry",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "isocountry"
}