-
Notifications
You must be signed in to change notification settings - Fork 60
/
Copy pathurn.py
55 lines (45 loc) · 1.62 KB
/
urn.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import re
from typing import Dict
from pandasdmx.model import PACKAGE, MaintainableArtefact
# Regular expression for URNs
URN = re.compile(
r"urn:sdmx:org\.sdmx\.infomodel"
r"\.(?P<package>[^\.]*)"
r"\.(?P<class>[^=]*)=((?P<agency>[^:]*):)?"
r"(?P<id>[^\(\.]*)(\((?P<version>[\d\.]*)\))?"
r"(\.(?P<item_id>.*))?"
)
_BASE = (
"urn:sdmx:org.sdmx.infomodel.{package}.{obj.__class__.__name__}="
"{ma.maintainer.id}:{ma.id}({ma.version}){extra_id}"
)
def make(obj, maintainable_parent=None, strict=False):
"""Create an SDMX URN for `obj`.
If `obj` is not :class:`.MaintainableArtefact`, then `maintainable_parent`
must be supplied in order to construct the URN.
"""
if not isinstance(obj, MaintainableArtefact):
ma = maintainable_parent or obj.get_scheme()
extra_id = f".{obj.id}"
else:
ma = obj
extra_id = ""
if not isinstance(ma, MaintainableArtefact):
raise ValueError(
f"Neither {repr(obj)} nor {repr(maintainable_parent)} are maintainable"
)
elif ma.maintainer is None:
raise ValueError(f"Cannot construct URN for {repr(ma)} without maintainer")
elif strict and ma.version is None:
raise ValueError(f"Cannot construct URN for {repr(ma)} without version")
return _BASE.format(
package=PACKAGE[obj.__class__], obj=obj, ma=ma, extra_id=extra_id
)
def match(value: str) -> Dict[str, str]:
try:
match = URN.match(value)
assert match is not None
except AssertionError:
raise ValueError(f"not a valid SDMX URN: {value}")
else:
return match.groupdict()