Skip to content

Commit

Permalink
Merge pull request #45 from bis-med-it/lc_facets
Browse files Browse the repository at this point in the history
Add support for core and local representations
  • Loading branch information
sosna committed May 16, 2024
2 parents e5f8fc4 + e4eeede commit a54cdad
Show file tree
Hide file tree
Showing 13 changed files with 310 additions and 133 deletions.
83 changes: 36 additions & 47 deletions src/pysdmx/fmr/fusion/dsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,33 +36,19 @@ def _find_concept(

def _get_representation(
id_: str,
repr_: Optional[FusionRepresentation],
r: Optional[FusionRepresentation],
cls: Sequence[FusionCodelist],
cons: Dict[str, Sequence[str]],
c: Optional[FusionConcept],
) -> Tuple[
DataType,
Optional[DataType],
Optional[Facets],
Optional[Codelist],
Optional[ArrayBoundaries],
]:
valid = cons.get(id_, [])
ab = None
dt = DataType.STRING
facets = None
codes = None
if repr_:
r = repr_
elif c and c.representation:
r = c.representation
else:
r = None
if r:
if r.textFormat:
dt = DataType(r.textFormat.textType)
facets = r.to_facets()
codes = r.to_enumeration(cls, valid)
ab = r.to_array_def()
ab = r.to_array_def() if r else None
dt = DataType(r.textFormat.textType) if r and r.textFormat else None
facets = r.to_facets() if r else None
codes = r.to_enumeration(cls, cons.get(id_, [])) if r else None
return (dt, facets, codes, ab)


Expand Down Expand Up @@ -115,22 +101,23 @@ def to_model(
"""Returns an attribute."""
c = _find_concept(cs, self.concept)
dt, facets, codes, ab = _get_representation(
self.id, self.representation, cls, cons, c
self.id, self.representation, cls, cons
)
lvl = self.__derive_level(groups)
if c.descriptions:
desc = c.descriptions[0].value
else:
desc = None
return Component(
self.id,
self.mandatory,
Role.ATTRIBUTE,
dt,
facets,
c.names[0].value,
desc,
codes=codes,
id=self.id,
required=self.mandatory,
role=Role.ATTRIBUTE,
concept=c.to_model(cls),
local_dtype=dt,
local_facets=facets,
name=c.names[0].value,
description=desc,
local_codes=codes,
attachment_level=lvl,
array_def=ab,
)
Expand Down Expand Up @@ -168,21 +155,22 @@ def to_model(
"""Returns a dimension."""
c = _find_concept(cs, self.concept)
dt, facets, codes, ab = _get_representation(
self.id, self.representation, cls, cons, c
self.id, self.representation, cls, cons
)
if c.descriptions:
desc = c.descriptions[0].value
else:
desc = None
return Component(
self.id,
True,
Role.DIMENSION,
dt,
facets,
c.names[0].value,
desc,
codes=codes,
id=self.id,
required=True,
role=Role.DIMENSION,
concept=c.to_model(cls),
local_dtype=dt,
local_facets=facets,
name=c.names[0].value,
description=desc,
local_codes=codes,
array_def=ab,
)

Expand Down Expand Up @@ -219,21 +207,22 @@ def to_model(
"""Returns a measure."""
c = _find_concept(cs, self.concept)
dt, facets, codes, ab = _get_representation(
self.id, self.representation, cls, cons, c
self.id, self.representation, cls, cons
)
if c.descriptions:
desc = c.descriptions[0].value
else:
desc = None
return Component(
self.id,
self.mandatory,
Role.MEASURE,
dt,
facets,
c.names[0].value,
desc,
codes=codes,
id=self.id,
required=self.mandatory,
role=Role.MEASURE,
concept=c.to_model(cls),
local_dtype=dt,
local_facets=facets,
name=c.names[0].value,
description=desc,
local_codes=codes,
array_def=ab,
)

Expand Down
2 changes: 1 addition & 1 deletion src/pysdmx/fmr/fusion/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def to_model(
comp_id = parse_item_urn(ha.component_ref).item_id
h = msgspec.structs.replace(ha.hierarchy, operator=ha.operator)
comp_dict[comp_id] = msgspec.structs.replace(
components[comp_id], codes=h
components[comp_id], local_codes=h
)
urns.append(
"urn:sdmx:org.sdmx.infomodel.codelist.Hierarchy="
Expand Down
11 changes: 5 additions & 6 deletions src/pysdmx/fmr/sdmx/concept.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from pysdmx.fmr.sdmx.code import JsonCodelist
from pysdmx.fmr.sdmx.core import JsonRepresentation
from pysdmx.model import Concept, ConceptScheme, DataType
from pysdmx.model import Codelist, Concept, ConceptScheme, DataType


class JsonConcept(Struct, frozen=True):
Expand All @@ -17,7 +17,7 @@ class JsonConcept(Struct, frozen=True):
name: Optional[str] = None
description: Optional[str] = None

def to_model(self, codelists: Sequence[JsonCodelist]) -> Concept:
def to_model(self, codelists: Sequence[Codelist]) -> Concept:
"""Converts a JsonConcept to a standard concept."""
repr_ = self.coreRepresentation
if repr_:
Expand All @@ -30,9 +30,7 @@ def to_model(self, codelists: Sequence[JsonCodelist]) -> Concept:
repr_.format.textType, # type: ignore[union-attr]
)
facets = repr_.to_facets()
codes = repr_.to_enumeration(
[cl.to_model() for cl in codelists], []
)
codes = repr_.to_enumeration(codelists, [])
cl_ref = repr_.enumeration
else:
dt = DataType.STRING
Expand Down Expand Up @@ -62,13 +60,14 @@ class JsonConceptScheme(Struct, frozen=True, rename={"agency": "agencyID"}):

def to_model(self, codelists: Sequence[JsonCodelist]) -> ConceptScheme:
"""Converts a JsonConceptScheme to a standard concept scheme."""
cls = [c.to_model() for c in codelists]
return ConceptScheme(
id=self.id,
name=self.name,
agency=self.agency,
description=self.description,
version=self.version,
items=[c.to_model(codelists) for c in self.concepts],
items=[c.to_model(cls) for c in self.concepts],
)


Expand Down
78 changes: 35 additions & 43 deletions src/pysdmx/fmr/sdmx/dsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,30 +42,19 @@ def __get_type(repr_: JsonRepresentation) -> str:
def _get_representation(
id_: str,
local: Optional[JsonRepresentation],
core: Optional[JsonRepresentation],
cls: Sequence[Codelist],
cons: Dict[str, Sequence[str]],
) -> Tuple[
DataType,
Optional[DataType],
Optional[Facets],
Optional[Codelist],
Optional[ArrayBoundaries],
]:
valid = cons.get(id_, [])
codes = None
dt = DataType.STRING
facets = None
ab = None
if local:
dt = DataType(__get_type(local))
facets = local.to_facets()
codes = local.to_enumeration(cls, valid)
ab = local.to_array_def()
elif core:
dt = DataType(__get_type(core))
facets = core.to_facets()
codes = core.to_enumeration(cls, valid)
ab = core.to_array_def()
codes = local.to_enumeration(cls, valid) if local else None
dt = DataType(__get_type(local)) if local else None
facets = local.to_facets() if local else None
ab = local.to_array_def() if local else None
return (dt, facets, codes, ab)


Expand Down Expand Up @@ -113,17 +102,18 @@ def to_model(
"""Returns a component."""
c = _find_concept(cs, self.conceptIdentity)
dt, facets, codes, ab = _get_representation(
self.id, self.localRepresentation, c.coreRepresentation, cls, cons
self.id, self.localRepresentation, cls, cons
)
return Component(
self.id,
True,
Role.DIMENSION,
dt,
facets,
c.name,
c.description,
codes=codes,
id=self.id,
required=True,
role=Role.DIMENSION,
concept=c.to_model(cls),
local_dtype=dt,
local_facets=facets,
name=c.name,
description=c.description,
local_codes=codes,
array_def=ab,
)

Expand All @@ -148,22 +138,23 @@ def to_model(
"""Returns a component."""
c = _find_concept(cs, self.conceptIdentity)
dt, facets, codes, ab = _get_representation(
self.id, self.localRepresentation, c.coreRepresentation, cls, cons
self.id, self.localRepresentation, cls, cons
)
req = self.usage != "optional"
lvl = self.attributeRelationship.to_model(
groups,
self.measureRelationship,
)
return Component(
self.id,
req,
Role.ATTRIBUTE,
dt,
facets,
c.name,
c.description,
codes=codes,
id=self.id,
required=req,
role=Role.ATTRIBUTE,
concept=c.to_model(cls),
local_dtype=dt,
local_facets=facets,
name=c.name,
description=c.description,
local_codes=codes,
attachment_level=lvl,
array_def=ab,
)
Expand All @@ -186,18 +177,19 @@ def to_model(
"""Returns a component."""
c = _find_concept(cs, self.conceptIdentity)
dt, facets, codes, ab = _get_representation(
self.id, self.localRepresentation, c.coreRepresentation, cls, cons
self.id, self.localRepresentation, cls, cons
)
req = self.usage != "optional"
return Component(
self.id,
req,
Role.MEASURE,
dt,
facets,
c.name,
c.description,
codes=codes,
id=self.id,
required=req,
role=Role.MEASURE,
concept=c.to_model(cls),
local_dtype=dt,
local_facets=facets,
name=c.name,
description=c.description,
local_codes=codes,
array_def=ab,
)

Expand Down
2 changes: 1 addition & 1 deletion src/pysdmx/fmr/sdmx/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def to_model(
comp_id = parse_item_urn(ha.component_ref).item_id
h = msgspec.structs.replace(ha.hierarchy, operator=ha.operator)
comp_dict[comp_id] = msgspec.structs.replace(
components[comp_id], codes=h
components[comp_id], local_codes=h
)
urns.append(
"urn:sdmx:org.sdmx.infomodel.codelist.Hierarchy="
Expand Down
2 changes: 1 addition & 1 deletion src/pysdmx/model/concept.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class Concept(Item, frozen=True, omit_defaults=True):
which the codes are taken.
"""

dtype: DataType = DataType.STRING
dtype: Optional[DataType] = None
facets: Optional[Facets] = None
codes: Optional[Codelist] = None
enum_ref: Optional[str] = None
Expand Down
Loading

0 comments on commit a54cdad

Please sign in to comment.