iso3901


Nameiso3901 JSON
Version 0.3.3 PyPI version JSON
download
home_pageNone
SummaryStructured parsing of ISRC (International Standard Recording Code), as defined in ISO 3901:2019
upload_time2024-10-15 08:14:35
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseNone
keywords isrc recording sound metadata ifpi
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![PyPI version](https://img.shields.io/pypi/v/iso3901.svg)](https://pypi.org/project/iso3901/)
![Supported Python](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fgithub.com%2FTagger-phile%2Fpy-iso3901%2Fraw%2Frefs%2Fheads%2Fmain%2Fpyproject.toml)
![Wheel](https://img.shields.io/pypi/wheel/iso3901.svg)

# py-iso3901
Structured parsing of ISRC ([International Standard Recording Code](https://isrc.ifpi.org/en/)) in python, as defined in ISO 3901:2019.

## Install

`pip install -U iso3901`

## Usage Example

The most usual way to create object is via `ISRC.parse` method:

```pycon
>>> from iso3901 import ISRC

>>> data = ISRC.parse('ISRC GB-AJY-12-34567')
>>> data == ISRC.parse('GBAJY1234567')  # Same as compact form
True
>>> data.country.name
'United Kingdom of Great Britain and Northern Ireland'
>>> data.owner
'GBAJY'
>>> data.prefix
'GB'
>>> data.year
12
>>> data.designation
34567
>>> data.agency
'PPL UK'
>>> str(data)
'GBAJY1234567'
>>> data.stringify()
'GB-AJY-12-34567'
>>> data.raw  # Get back the original unparsed string
'ISRC GB-AJY-12-34567'
```

ISRC agency prefix validation is now supported since version `0.3.0`:
```pycon
>>> data = ISRC.parse('QMDA71418090')
>>> data.country.name
'United States of America'
>>> data.country.alpha2, data.prefix
('US', 'QM')
>>> data.agency
'RIAA'
>>> data = ISRC.parse('ZZZZZ1234567')
>>> data.country.name
'Worldwide'
>>> data.country.alpha2
''
>>> data.agency
'International ISRC Registration Authority'
```

`validate()` method is provided for simple validation:

```pycon
>>> ISRC.validate('aa-xyz-01-23456')
True
>>> ISRC.validate('aa-xyz-012-3456')
False
```

If desired, ISRC prefix allocation status and agency names can be accessed directly. They are exported directly as standard [`enum`](https://docs.python.org/3/library/enum.html):

```pycon
>>> from iso3901 import Agency, Allocation
>>> Agency.DK
<Agency.DK: 'GRAMEK DK'>
>>> Agency.DK == Agency['DK']
True
>>> Allocation.DK
<Allocation.DK: ......>
>>> Allocation.DK.agency == Agency.DK
True
>>> Allocation['DK'].country
Country(name='Denmark', alpha2='DK', alpha3='DNK', numeric='208', apolitical_name='Denmark')
>>> Allocation['XY']
Traceback (most recent call last):
......
KeyError: 'XY'
```

## Caveats

In the _very rare_ case that no data validation is desired, it is possible to initiate object directly. Be warned that supplying free form data would result in illegal ISRC code:

```pycon
>>> data = ISRC('GBAJY', 12, 34567)
>>> str(data)
'GBAJY1234567'
>>> data = ISRC('Some Owner', 123, 456789)
>>> str(data)
'Some Owner123456789'
```

In case ISRC prefix isn't a legal allocated prefix, `.country` and `.agency` properties become `None`:

```pycon
>>> data = ISRC('ZYXWV', 12, 34567)  # Exception if using ISRC.parse()
>>> type(data.country)
<class 'NoneType'>
>>> type(data.agency)
<class 'NoneType'>
```

## Reference

Following documents are consulted when writing code:

- [ISRC Handbook, 4th edition](https://www.ifpi.org/wp-content/uploads/2021/02/ISRC_Handbook.pdf)
- [ISRC Agency Bulletin 2015/01](https://isrc.ifpi.org/downloads/ISRC_Bulletin-2015-01.pdf)
- [Newest valid ISRC prefixes](https://isrc.ifpi.org/downloads/Valid_Characters.pdf)

## Q&A

1. _Why is there no validation for invalid registrants, such as `US-S1Z` which is mentioned in above documents?_

   It is true that ISRC agencies has been repeatedly mentioning that some codes were "for illustrative purposes in documentation and training materials", and therefore are known invalid codes. However, registrant allocation info is not public; it is held privately within allocator of each nation (and most likely International ISRC Agency itself). It is practically impossible to exhaust and blacklist all examples used in various documents on internet. In single word: _unenforceable_.

2. _Why is the year kept as integer and not python `datetime` structure?_

   In ISRC standard, only the last 2 digit of year is available. It is easier to tell the actual year in some cases, but for years like '20', it is impossible to distinguish 1920 from 2020 via ISRC alone. Acoustic recording already existed around 1900; and some ancient recordings are known to directly use recording year (20's) in ISRC, such as [Jimmie Rodgers'](https://open.spotify.com/album/6TXhBKNTITmOTWCbHaQKIG).

3. _The "country code" `QM` is already known for use in United States, and `ZZ` reserved for International ISRC Agency, as described in various ISRC Bulletins. Is there any plan to add modern ISRC Registrant allocations and do a mapping between newer prefixes and countries?_

   Actually, the newest bulletin dated 2015 had pushed a new standard that no more binds country with the 2-letter prefix. That said, since `0.3.0` version, country code is validated to conform to [newest published prefixes](https://isrc.ifpi.org/downloads/Valid_Characters.pdf) &mdash; Jun 2024 as of writing. There exists quite a number of countries unmanaged by any recording industry agencies, so validation still provides some benefit.

## Alternatives

If one only needs to check for validity of ISRC string, and no objectified access of various segments is needed, other python modules exist to provide such validation routine. For example:

- [python-stdnum](https://pypi.org/project/python-stdnum/)
- [py.validator](https://pypi.org/project/py-validator/)

However, so far this package provides the most rigorous validation among all of the choices, as it contains the newest country prefixes mapping.


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "iso3901",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "isrc, recording, sound, metadata, ifpi",
    "author": null,
    "author_email": "Abel Cheung <abelcheung@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/e4/17/9bbccc20395d965259f9b93fbbe165c5755b172982e3edc24ecb0933585c/iso3901-0.3.3.tar.gz",
    "platform": null,
    "description": "[![PyPI version](https://img.shields.io/pypi/v/iso3901.svg)](https://pypi.org/project/iso3901/)\n![Supported Python](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fgithub.com%2FTagger-phile%2Fpy-iso3901%2Fraw%2Frefs%2Fheads%2Fmain%2Fpyproject.toml)\n![Wheel](https://img.shields.io/pypi/wheel/iso3901.svg)\n\n# py-iso3901\nStructured parsing of ISRC ([International Standard Recording Code](https://isrc.ifpi.org/en/)) in python, as defined in ISO 3901:2019.\n\n## Install\n\n`pip install -U iso3901`\n\n## Usage Example\n\nThe most usual way to create object is via `ISRC.parse` method:\n\n```pycon\n>>> from iso3901 import ISRC\n\n>>> data = ISRC.parse('ISRC GB-AJY-12-34567')\n>>> data == ISRC.parse('GBAJY1234567')  # Same as compact form\nTrue\n>>> data.country.name\n'United Kingdom of Great Britain and Northern Ireland'\n>>> data.owner\n'GBAJY'\n>>> data.prefix\n'GB'\n>>> data.year\n12\n>>> data.designation\n34567\n>>> data.agency\n'PPL UK'\n>>> str(data)\n'GBAJY1234567'\n>>> data.stringify()\n'GB-AJY-12-34567'\n>>> data.raw  # Get back the original unparsed string\n'ISRC GB-AJY-12-34567'\n```\n\nISRC agency prefix validation is now supported since version `0.3.0`:\n```pycon\n>>> data = ISRC.parse('QMDA71418090')\n>>> data.country.name\n'United States of America'\n>>> data.country.alpha2, data.prefix\n('US', 'QM')\n>>> data.agency\n'RIAA'\n>>> data = ISRC.parse('ZZZZZ1234567')\n>>> data.country.name\n'Worldwide'\n>>> data.country.alpha2\n''\n>>> data.agency\n'International ISRC Registration Authority'\n```\n\n`validate()` method is provided for simple validation:\n\n```pycon\n>>> ISRC.validate('aa-xyz-01-23456')\nTrue\n>>> ISRC.validate('aa-xyz-012-3456')\nFalse\n```\n\nIf desired, ISRC prefix allocation status and agency names can be accessed directly. They are exported directly as standard [`enum`](https://docs.python.org/3/library/enum.html):\n\n```pycon\n>>> from iso3901 import Agency, Allocation\n>>> Agency.DK\n<Agency.DK: 'GRAMEK DK'>\n>>> Agency.DK == Agency['DK']\nTrue\n>>> Allocation.DK\n<Allocation.DK: ......>\n>>> Allocation.DK.agency == Agency.DK\nTrue\n>>> Allocation['DK'].country\nCountry(name='Denmark', alpha2='DK', alpha3='DNK', numeric='208', apolitical_name='Denmark')\n>>> Allocation['XY']\nTraceback (most recent call last):\n......\nKeyError: 'XY'\n```\n\n## Caveats\n\nIn the _very rare_ case that no data validation is desired, it is possible to initiate object directly. Be warned that supplying free form data would result in illegal ISRC code:\n\n```pycon\n>>> data = ISRC('GBAJY', 12, 34567)\n>>> str(data)\n'GBAJY1234567'\n>>> data = ISRC('Some Owner', 123, 456789)\n>>> str(data)\n'Some Owner123456789'\n```\n\nIn case ISRC prefix isn't a legal allocated prefix, `.country` and `.agency` properties become `None`:\n\n```pycon\n>>> data = ISRC('ZYXWV', 12, 34567)  # Exception if using ISRC.parse()\n>>> type(data.country)\n<class 'NoneType'>\n>>> type(data.agency)\n<class 'NoneType'>\n```\n\n## Reference\n\nFollowing documents are consulted when writing code:\n\n- [ISRC Handbook, 4th edition](https://www.ifpi.org/wp-content/uploads/2021/02/ISRC_Handbook.pdf)\n- [ISRC Agency Bulletin 2015/01](https://isrc.ifpi.org/downloads/ISRC_Bulletin-2015-01.pdf)\n- [Newest valid ISRC prefixes](https://isrc.ifpi.org/downloads/Valid_Characters.pdf)\n\n## Q&A\n\n1. _Why is there no validation for invalid registrants, such as `US-S1Z` which is mentioned in above documents?_\n\n   It is true that ISRC agencies has been repeatedly mentioning that some codes were \"for illustrative purposes in documentation and training materials\", and therefore are known invalid codes. However, registrant allocation info is not public; it is held privately within allocator of each nation (and most likely International ISRC Agency itself). It is practically impossible to exhaust and blacklist all examples used in various documents on internet. In single word: _unenforceable_.\n\n2. _Why is the year kept as integer and not python `datetime` structure?_\n\n   In ISRC standard, only the last 2 digit of year is available. It is easier to tell the actual year in some cases, but for years like '20', it is impossible to distinguish 1920 from 2020 via ISRC alone. Acoustic recording already existed around 1900; and some ancient recordings are known to directly use recording year (20's) in ISRC, such as [Jimmie Rodgers'](https://open.spotify.com/album/6TXhBKNTITmOTWCbHaQKIG).\n\n3. _The \"country code\" `QM` is already known for use in United States, and `ZZ` reserved for International ISRC Agency, as described in various ISRC Bulletins. Is there any plan to add modern ISRC Registrant allocations and do a mapping between newer prefixes and countries?_\n\n   Actually, the newest bulletin dated 2015 had pushed a new standard that no more binds country with the 2-letter prefix. That said, since `0.3.0` version, country code is validated to conform to [newest published prefixes](https://isrc.ifpi.org/downloads/Valid_Characters.pdf) &mdash; Jun 2024 as of writing. There exists quite a number of countries unmanaged by any recording industry agencies, so validation still provides some benefit.\n\n## Alternatives\n\nIf one only needs to check for validity of ISRC string, and no objectified access of various segments is needed, other python modules exist to provide such validation routine. For example:\n\n- [python-stdnum](https://pypi.org/project/python-stdnum/)\n- [py.validator](https://pypi.org/project/py-validator/)\n\nHowever, so far this package provides the most rigorous validation among all of the choices, as it contains the newest country prefixes mapping.\n\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Structured parsing of ISRC (International Standard Recording Code), as defined in ISO 3901:2019",
    "version": "0.3.3",
    "project_urls": {
        "Home": "https://github.com/Tagger-phile/py-iso3901"
    },
    "split_keywords": [
        "isrc",
        " recording",
        " sound",
        " metadata",
        " ifpi"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f7ec8b20380f92ff9f8660ca66b66ba8b42468aa6a1b3003023749a30c5bc15f",
                "md5": "d7ed01217f43a1ae55c2140c804f7c70",
                "sha256": "68ae39bb16afbb974d72f496dacda6de191d5d3ece7e0d3fcf6797d1b61b346e"
            },
            "downloads": -1,
            "filename": "iso3901-0.3.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d7ed01217f43a1ae55c2140c804f7c70",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 9924,
            "upload_time": "2024-10-15T08:14:33",
            "upload_time_iso_8601": "2024-10-15T08:14:33.402467Z",
            "url": "https://files.pythonhosted.org/packages/f7/ec/8b20380f92ff9f8660ca66b66ba8b42468aa6a1b3003023749a30c5bc15f/iso3901-0.3.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e4179bbccc20395d965259f9b93fbbe165c5755b172982e3edc24ecb0933585c",
                "md5": "fb42353a3d5900150d925230725acadf",
                "sha256": "7888e5fc0dc01b1d7628ea1afd86334c619961255099d0d91518140b751bc33c"
            },
            "downloads": -1,
            "filename": "iso3901-0.3.3.tar.gz",
            "has_sig": false,
            "md5_digest": "fb42353a3d5900150d925230725acadf",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 18102,
            "upload_time": "2024-10-15T08:14:35",
            "upload_time_iso_8601": "2024-10-15T08:14:35.336961Z",
            "url": "https://files.pythonhosted.org/packages/e4/17/9bbccc20395d965259f9b93fbbe165c5755b172982e3edc24ecb0933585c/iso3901-0.3.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-15 08:14:35",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Tagger-phile",
    "github_project": "py-iso3901",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "iso3901"
}
        
Elapsed time: 0.36866s