open-xpd-uuid-lib
A library of common functions used when creating and managing open-xpd-uuid, a common, globally-unique name space (uuid) for Product Declarations, including HPDs and EPDs, to help users find all environmental and health information related to a single product.
Open xPD UUID (short readable GUIDs)
open-xpd-uuid is a string that consists of 8 or 10 (8+2) alpha-numeric characters and any number of dashes.
For example: 123ABCED, 123ABCEDAR, ASB21M01, avbDK93S, -AB-11-cc-Ll---.
GUIDs that consists of the following characters 1234567890ABCDEFGHJKMNPQRSTUWXYZ (I, L, O, and V are not
mentioned)
are called "canonical". For example: 12345678, ABCDEFG1, 123ABCEDAR.
GUIDs that consists of 10 characters represent 8-character guid with appended 2-character checksum.
Checksum allows to detect 1-character entry errors and character swaps, and most other errors.
Character treatment
-or dash - is ignoredLorlorIori- is treated as1Ooro- is treated as0(zero)
Install
pip install open-xpd-uuid-lib
Supported versions
- The library is tested with the following Python versions:
- Python 3.10
- Python 3.11
- Python 3.12
- Python 3.13
- Python 3.14
- The minimal supported Python version is 3.10.
- Compatibility with future Python 3.x versions is expected but not guaranteed.
Usage
Generate short readable GUID
>>> from cqd import open_xpd_uuid
>>> open_xpd_uuid.generate()
'JKGEE5PN'
Generate short readable GUID starting with specific characters set (prefix)
>>> from cqd import open_xpd_uuid
>>> open_xpd_uuid.generate("CQD")
'CQD55PG0'
If you wish to issue your own openEPD IDs, you can request any three-symbol prefix that is not already reserved.
- "EC3" is reserved for BuildingTransparency.org
- "EST" is reserved for generic estimates
- "CQD" and "WAP" are reserved for WAP Sustainability
- "PCR" is reserved for designating product category rules
- "UL" is reserved for UL Sustainability
To request your own prefix, please email open-epd-forum@c-change-labs.com.
Sanitize short readable GUIDs
Use sanitize to replace ambiguous chars (0,o,O,1,L,l,I,i) with correct ones and remove dashes (-).
This function is useful to turn guid received from a user into a canonical one.
For example: as-b2-lm-oL -> ASB21M01
>>> from cqd import open_xpd_uuid
>>> open_xpd_uuid.sanitize("as-b2-lm-oL")
'ASB21M01'
Validate short readable GUID
Use validate to validate short readable GUID and get error description if the GUID is not valid.
validate accepts only "canonical" GUIDs: use sanitize function to make them "canonical".
>>> from cqd import open_xpd_uuid
>>> sanitized_guid = open_xpd_uuid.sanitize("as-b2-lm-oL")
>>> sanitized_guid
'ASB21M01'
>>> open_xpd_uuid.validate(sanitized_guid)
# no exception - the `sanitized_guid` is valid
>>> try:
... open_xpd_uuid.validate("as-b2-lm-oL")
... except open_xpd_uuid.GuidValidationError as e:
... print(e)
`guid` length must be 8 characters long
Match open xPD UUIDs with regex
Use the provided regex constants to recognize UUIDs in either accepted input form or canonical form.
The patterns are not anchored, so you can choose full validation (fullmatch) or extraction (finditer).
When extracting with search/finditer, apply token-boundary post-filtering (adjacent characters must not be
alphanumeric or -) to avoid partial matches inside longer tokens.
Even when using regex, prefer open_xpd_uuid.validate for actual GUID validation (including checksum validation for
10-character GUIDs).
>>> import re
...
... from cqd import open_xpd_uuid
...
... re.fullmatch(open_xpd_uuid.OPEN_XPD_UUID_REGEX, "-AB-11-cc-Ll---") is not None
True
>>> open_xpd_uuid.CANONICAL_OPEN_XPD_UUID_PATTERN.fullmatch("AB11CC11") is not None
True
>>> open_xpd_uuid.CANONICAL_OPEN_XPD_UUID_PATTERN.fullmatch("-AB-11-cc-Ll---") is not None
False
>>> text = "IDs: 123ABCED and -AB-11-cc-Ll---"
>>> token_chars = set("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
>>> matches = []
>>> for match in open_xpd_uuid.OPEN_XPD_UUID_PATTERN.finditer(text):
... start, end = match.span()
... previous_char = text[start - 1] if start > 0 else ""
... next_char = text[end] if end < len(text) else ""
... if previous_char not in token_chars and next_char not in token_chars:
... matches.append(match.group(0))
>>> matches
['123ABCED', '-AB-11-cc-Ll---']
Generate and use checksum
>>> from cqd import open_xpd_uuid
>>> guid = open_xpd_uuid.generate()
'JKGEE5PN'
>>> checksum = open_xpd_uuid.checksum(guid)
'ME'
>>> guid_with_checksum = guid + checksum
'JKGEE5PNME'
>>> short_link = "cqd.io/e/" + guid_with_checksum
'cqd.io/e/JKGEE5PNME'
Remove checksum from canonical GUID
Use remove_checksum when you need the base 8-character canonical UUID.
It accepts UUIDs with or without checksum, case-insensitively, preserves input casing, and also accepts None.
>>> from cqd import open_xpd_uuid
>>> open_xpd_uuid.remove_checksum("EC3949XK04")
'EC3949XK'
>>> open_xpd_uuid.remove_checksum("ec3949xk04")
'ec3949xk'
>>> open_xpd_uuid.remove_checksum("EC3949XK")
'EC3949XK'
>>> open_xpd_uuid.remove_checksum(None) is None
True
Convert any open xPD UUID to canonical UUID without checksum
Use canonical_without_checksum to combine sanitize, validate, and remove_checksum in one call.
It accepts any open xPD UUID form (dashes, lowercase, ambiguous characters) or None.
Set none_on_error=True to return None for invalid UUIDs instead of raising an error.
>>> from cqd import open_xpd_uuid
>>> open_xpd_uuid.canonical_without_checksum("as-b2-lm-oL")
'ASB21M01'
>>> open_xpd_uuid.canonical_without_checksum("EC3949XK04")
'EC3949XK'
>>> open_xpd_uuid.canonical_without_checksum("invalid", none_on_error=True) is None
True
>>> open_xpd_uuid.canonical_without_checksum(None) is None
True
Metadata
Release files for open-xpd-uuid 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| open_xpd_uuid-2.0.0.tar.gz | 10.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| open_xpd_uuid-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.1 kB
Release files / open_xpd_uuid-2.0.0.tar.gz
| Download URL | open_xpd_uuid-2.0.0.tar.gz |
|---|---|
| Size | 10.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2c7941e95a2bc81bac5af3fefef6a7883c9f74403d647e80e171ee0a0181eedc
|
|
BLAKE2b-256 checksum How to use checksums |
422406bee0310f48d657802618fd30e66f5434e38852609b4a9f5ec27b80d898
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.3 CPython/3.10.21 Linux/6.17.0-1022-azure
|
Release files / open_xpd_uuid-2.0.0-py3-none-any.whl
| Download URL | open_xpd_uuid-2.0.0-py3-none-any.whl |
|---|---|
| Size | 11.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fd9830c1842021ff872e324bb8d9f0a2438c4745f6b47c9e034ef7ed0b5b2ff6
|
|
BLAKE2b-256 checksum How to use checksums |
fe9c99c342b9305b01e7d19c77eeda9284ac3e3c114608f5ad07e21fd7f27334
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.3 CPython/3.10.21 Linux/6.17.0-1022-azure
|