Skip to main content

PyPI version Supported Python Wheel

py-iso3901

Structured parsing of ISRC (International Standard Recording Code) 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:

>>> 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:

>>> data = ISRC.parse('QMDA71418090')
>>> data.country.name
'United States of America'
>>> data.country.alpha2, data.prefix
('US', 'QM')
>>> data.agency
'RIAA'
>>> data.prefix_retired
False
>>> data = ISRC.parse('ZZZZZ1234567')
>>> data.country.name
'Worldwide'
>>> data.country.alpha2
''
>>> data.agency
'International ISRC Registration Authority'

validate() method is provided for simple validation:

>>> 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:

>>> 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'

Finally, it is noteworthy that prefix allocation date is available as python date constant:

>>> import iso3901
>>> iso3901.DB_DATE
datetime.date(2025, 11, 4)

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:

>>> 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:

>>> 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:

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'.

  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 — Nov 2025 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:

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

Metadata

Release files for iso3901 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for iso3901 1.1.0
File Size Uploaded
iso3901-1.1.0.tar.gz 12.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for iso3901 1.1.0
File Interpreter ABI Platform
iso3901-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 23.3 kB

Release files / iso3901-1.1.0.tar.gz

Download URL iso3901-1.1.0.tar.gz
Size 12.6 kB
Tags Source
SHA-256 checksum
How to use checksums
7b0a3371d4d1a368c307816efe46c459c5ce2d81d79a5c53c1f57acaae470199
BLAKE2b-256 checksum
How to use checksums
abd9a5e7258fae6b9a1a86666e93e1b4fbd02f050997be41b8f94add916115ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 18, 2025.

Transparency log

Release files / iso3901-1.1.0-py3-none-any.whl

Download URL iso3901-1.1.0-py3-none-any.whl
Size 10.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
46642f0f18c0871bf37878fc399f68a59375fe5452a49db86fa8ce1624416fc0
BLAKE2b-256 checksum
How to use checksums
63e5bc0031609c1f916c6772518b951907ce62adadad4da5a8681fed70c2dcde
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 18, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page