Skip to content

Commit c8356c1

Browse files
committed
🎨 review code and closes brazil-data-cube#73 brazil-data-cube#72
1 parent a2d5134 commit c8356c1

File tree

7 files changed

+224
-210
lines changed

7 files changed

+224
-210
lines changed

lccs/classes.py

Lines changed: 73 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -16,117 +16,118 @@
1616
# along with this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
1717
#
1818
"""Python Client Library for the LCCS Web Service."""
19+
from typing import List, Optional
1920
from .utils import Utils
2021

2122

2223
class ClassesGroup(dict):
23-
"""Group of classes mappings."""
24+
"""Group of classification system classes."""
2425

25-
def __init__(self, data, validate=False):
26-
"""Initialize instance with dictionary data.
26+
def __init__(self, data: dict, validate: bool = False) -> None:
27+
"""
28+
Initialize instance with dictionary data.
2729
28-
:param data: Dict with Item Collection metadata.
29-
:param validate: true if the Item Collection should be validate using its jsonschema. Default is False.
30+
:param data: Dictionary containing classification group data.
31+
:param validate: Whether to validate the data using jsonschema. Default is False.
3032
"""
33+
super().__init__(data or {})
3134
self._validate = validate
32-
super(ClassesGroup, self).__init__(data or {})
33-
self._classes = [ClassificationSystemClass(i, self._validate) for i in self['classes']]
35+
self._classes: List[ClassificationSystemClass] = [
36+
ClassificationSystemClass(i, self._validate) for i in self.get('classes', [])
37+
]
3438

3539
@property
36-
def classes(self):
37-
""":return: classes."""
40+
def classes(self) -> List['ClassificationSystemClass']:
41+
"""Return the list of classification system classes."""
3842
return self._classes
3943

40-
def _repr_html_(self):
41-
"""HTML repr."""
44+
def _repr_html_(self) -> str:
45+
"""Render HTML representation."""
4246
return Utils.render_html('mapping.html', mappings=self)
4347

44-
def __repr__(self):
45-
"""Return the string representation of a mapping group object."""
46-
text = ''
47-
for i in self._classes:
48-
text += f'\n\t{i}'
49-
return text
48+
def __repr__(self) -> str:
49+
"""Return the string representation of the group."""
50+
return "\n".join([str(cls) for cls in self._classes])
5051

51-
def __str__(self):
52-
"""Return the string representation of a mapping group object."""
53-
text = ''
54-
for i in self._classes:
55-
text += f'\n\t{i}'
56-
return text
52+
def __str__(self) -> str:
53+
"""Return the string representation of the group (readable)."""
54+
return self.__repr__()
5755

5856

5957
class ClassificationSystemClass(dict):
60-
"""Class of the classification system."""
61-
62-
def __init__(self, data, validate=False) -> None:
63-
"""Initialize instance with dictionary data.
58+
"""Class representing a classification system."""
6459

65-
:param data: Dict with Class metadata.
60+
def __init__(self, data: dict, validate: bool = False) -> None:
61+
"""
62+
Initialize instance with dictionary data.
6663
67-
:param validate: true if the Class should be validate using its jsonschema. Default is False.
64+
:param data: Dictionary containing class metadata.
65+
:param validate: Whether to validate the data using jsonschema. Default is False.
6866
"""
67+
super().__init__(data or {})
6968
self._validate = validate
70-
super(ClassificationSystemClass, self).__init__(data or {})
7169

7270
@property
73-
def id(self):
74-
""":return: the class id."""
75-
return self['id']
71+
def id(self) -> str:
72+
"""Return the class ID."""
73+
return self.get('id')
7674

7775
@property
78-
def name(self):
79-
""":return: the class name."""
80-
return self['name']
76+
def name(self) -> str:
77+
"""Return the class name."""
78+
return self.get('name')
8179

8280
@property
83-
def title(self):
84-
""":return: the class title."""
85-
return self['title']
81+
def title(self) -> str:
82+
"""Return the class title."""
83+
return self.get('title')
8684

8785
@property
88-
def description(self):
89-
""":return: the class description."""
90-
return self['description'] if 'description' in self else None
86+
def description(self) -> Optional[str]:
87+
"""Return the class description."""
88+
return self.get('description')
9189

9290
@property
93-
def color(self):
94-
""":return: the class description."""
95-
return self['color'] if 'color' in self else None
91+
def color(self) -> Optional[str]:
92+
"""Return the class color."""
93+
return self.get('color')
9694

9795
@property
98-
def code(self):
99-
""":return: the class code."""
100-
return self['code']
96+
def code(self) -> str:
97+
"""Return the class code."""
98+
return self.get('code')
10199

102100
@property
103-
def links(self):
104-
""":return: the class links."""
105-
return self['links']
101+
def links(self) -> List[dict]:
102+
"""Return the class links."""
103+
return self.get('links', [])
106104

107105
@property
108-
def class_parent_id(self):
109-
""":return: the class parent id."""
110-
return self['class_parent_id'] if 'class_parent_id' in self else None
106+
def class_parent_id(self) -> Optional[str]:
107+
"""Return the parent class ID."""
108+
return self.get('class_parent_id')
111109

112110
@property
113-
def class_parent_name(self):
114-
""":return: class_parent_name of classification system."""
111+
def class_parent_name(self) -> Optional[str]:
112+
"""Return the parent class name."""
115113
return self._get_parent_name()
116114

117-
def _get_parent_name(self):
118-
if 'class_parent_id' in self:
119-
parent = [link['href'] for link in self['links'] if link['rel'] == 'parent'][0]
120-
system = parent.rsplit('/', maxsplit=1)[1].split('?')[0]
121-
122-
if len(parent.rsplit('/', maxsplit=1)[1].split('?')) > 1:
123-
token = parent.rsplit('/', maxsplit=1)[1].split('?')[1]
124-
parent_class_uri = parent.rsplit('/', maxsplit=1)[
125-
0] + f'/{system}' + f'/classes/{self["class_parent_id"]}?{token}'
126-
else:
127-
parent_class_uri = parent.rsplit('/', maxsplit=1)[
128-
0] + f'/{system}' + f'/classes/{self["class_parent_id"]}'
129-
class_parent_name = ClassificationSystemClass(Utils._get(parent_class_uri)).name
130-
return class_parent_name
131-
else:
132-
return None
115+
def _get_parent_name(self) -> Optional[str]:
116+
"""Resolve and return the parent class name, if available."""
117+
if self.class_parent_id:
118+
parent_link = next((link for link in self.links if link.get('rel') == 'parent'), None)
119+
if parent_link:
120+
try:
121+
parent_url = self._build_parent_url(parent_link['href'])
122+
parent_data = Utils._get(parent_url)
123+
return ClassificationSystemClass(parent_data).name
124+
except Exception as e:
125+
return None
126+
return None
127+
128+
def _build_parent_url(self, href: str) -> str:
129+
"""Build the full URL for the parent class."""
130+
system = href.rsplit('/', maxsplit=1)[1].split('?')[0]
131+
token = href.split('?')[-1] if '?' in href else ""
132+
base_url = href.rsplit('/', maxsplit=1)[0]
133+
return f"{base_url}/{system}/classes/{self['class_parent_id']}?{token}" if token else f"{base_url}/{system}/classes/{self['class_parent_id']}"

lccs/classification_system.py

Lines changed: 70 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -16,94 +16,114 @@
1616
# along with this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
1717
#
1818
"""Python Client Library for the LCCS Web Service."""
19-
from typing import Union, Any, List, Optional, cast
20-
19+
from typing import Union, Any, List, Optional
2120
from .classes import ClassificationSystemClass, ClassesGroup
2221
from .link import Link
2322
from .utils import Utils
2423

2524

2625
class ClassificationSystem(dict):
27-
"""Classification System Class."""
26+
"""Representation of a Classification System."""
2827

29-
def __init__(self, data, validate=False):
30-
"""Initialize instance with dictionary data.
28+
def __init__(self, data: dict, validate: bool = False) -> None:
29+
"""
30+
Initialize a classification system with metadata.
3131
32-
:param data: Dict with class system metadata.
33-
:param validate: true if the Class System should be validate using its jsonschema. Default is False.
32+
:param data: Dictionary containing classification system metadata.
33+
:param validate: Whether to validate the data using jsonschema. Default is False.
3434
"""
35+
super().__init__(data or {})
3536
self._validate = validate
36-
super(ClassificationSystem, self).__init__(data or {})
3737

3838
@property
3939
def id(self) -> int:
40-
""":return: id of classification system."""
41-
return self['id']
40+
"""Return the ID of the classification system."""
41+
return self.get('id')
4242

4343
@property
4444
def identifier(self) -> str:
45-
""":return: identifier of classification system."""
46-
return self['identifier']
45+
"""Return the identifier of the classification system."""
46+
return self.get('identifier')
4747

4848
@property
4949
def name(self) -> str:
50-
""":return: name of classification system."""
51-
return self['name']
50+
"""Return the name of the classification system."""
51+
return self.get('name')
5252

5353
@property
5454
def title(self) -> str:
55-
""":return: title of classification system."""
56-
return self['title']
55+
"""Return the title of the classification system."""
56+
return self.get('title')
5757

5858
@property
5959
def links(self) -> List[Link]:
60-
""":return: a list of link in the classification system."""
61-
return [Link(link) for link in self['links']]
60+
"""Return a list of links associated with the classification system."""
61+
return [Link(link) for link in self.get('links', [])]
6262

6363
@property
64-
def description(self) -> str:
65-
""":return: description of classification system."""
66-
return self['description']
64+
def description(self) -> Optional[str]:
65+
"""Return the description of the classification system."""
66+
return self.get('description')
6767

6868
@property
6969
def version(self) -> str:
70-
""":return: version of classification system."""
71-
return self['version']
70+
"""Return the version of the classification system."""
71+
return self.get('version')
7272

7373
@property
74-
def authority_name(self) -> str:
75-
""":return: authority_name of classification system."""
76-
return self['authority_name']
77-
78-
def classes(self, class_name_or_id: Optional[str] = None, style_format_name_or_id: Optional[str] = None) -> Union[ClassesGroup, ClassificationSystemClass]:
79-
""":return: classes of the classification system."""
80-
if style_format_name_or_id is not None:
81-
_classes_data = next(Utils._get(f"{link['href']}&style_format_id={style_format_name_or_id}") for link in self['links'] if link['rel'] == 'classes')
82-
83-
else:
84-
_classes_data = next(Utils._get(link['href']) for link in self['links'] if link['rel'] == 'classes')
85-
86-
87-
if class_name_or_id is not None:
88-
_classes_link = [link['href'] for link in self['links'] if link['rel'] == 'classes'][0]
89-
link = _classes_link.split('classes')
90-
data = Utils._get(f'{link[0]}classes/{class_name_or_id}{link[1]}')
91-
return ClassificationSystemClass(data, self._validate)
92-
93-
all_classes = ClassesGroup(dict(classes=_classes_data))
94-
return all_classes.classes
74+
def authority_name(self) -> Optional[str]:
75+
"""Return the authority name of the classification system."""
76+
return self.get('authority_name')
77+
78+
def classes(
79+
self,
80+
class_name_or_id: Optional[str] = None,
81+
style_format_name_or_id: Optional[str] = None
82+
) -> Union[ClassesGroup, ClassificationSystemClass]:
83+
"""
84+
Return the classes of the classification system.
9585
96-
def _repr_html_(self):
97-
"""HTML repr."""
86+
:param class_name_or_id: Name or ID of a specific class. Default is None.
87+
:param style_format_name_or_id: Style format ID for filtering classes. Default is None.
88+
:return: A group of classes or a specific classification system class.
89+
"""
90+
try:
91+
if style_format_name_or_id:
92+
classes_url = next(
93+
link['href'] + f"&style_format_id={style_format_name_or_id}"
94+
for link in self.get('links', []) if link.get('rel') == 'classes'
95+
)
96+
else:
97+
classes_url = next(
98+
link['href'] for link in self.get('links', []) if link.get('rel') == 'classes'
99+
)
100+
classes_data = Utils._get(classes_url)
101+
102+
if class_name_or_id:
103+
classes_link = next(
104+
link['href'] for link in self.get('links', []) if link.get('rel') == 'classes'
105+
)
106+
base_url, params = classes_link.split('classes', 1)
107+
specific_class_data = Utils._get(f"{base_url}classes/{class_name_or_id}{params}")
108+
return ClassificationSystemClass(specific_class_data, self._validate)
109+
110+
all_classes = ClassesGroup({"classes": classes_data})
111+
return all_classes.classes
112+
except StopIteration:
113+
raise ValueError("No 'classes' link found in the classification system.")
114+
except Exception as e:
115+
raise RuntimeError(f"An error occurred while retrieving classes: {e}")
116+
117+
def _repr_html_(self) -> str:
118+
"""Render an HTML representation of the classification system."""
98119
return Utils.render_html('classification_system.html', classification_system=self)
99120

100121
def __repr__(self) -> str:
101-
"""Return the string representation of a classification system object."""
102-
text = f'{self.id}:{self.name}-{self.version} - Title: {self.title}'
103-
return text
122+
"""Return the string representation of the classification system."""
123+
return f'{self.id}:{self.name}-{self.version} - Title: {self.title}'
104124

105125
def __str__(self) -> str:
106-
"""Return the string representation of a classification system object."""
126+
"""Return a human-readable string representation of the classification system."""
107127
return f'<Classification System [{self.id}:{self.name}-{self.version} - Title: {self.title}]>'
108128

109129

lccs/lccs.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,6 @@ def delete_mapping(self, system_source: str, system_target: str) -> int:
345345

346346
return retval.status_code
347347

348-
#TODO
349348
def create_style(self, system: str, style_format: str, options: dict, rules: list):
350349
"""Create style sld."""
351350
sld = SldGenerator.create_sld(options=options, rules=rules, layer_name=system)

lccs/link.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,29 @@
2121
class Link(dict):
2222
"""Link object."""
2323

24-
def __init__(self, data):
24+
def __init__(self, data) -> None:
2525
"""Initialize instance with dictionary data.
2626
2727
:param data: Dict with Link metadata.
2828
"""
2929
super(Link, self).__init__(data or {})
3030

3131
@property
32-
def rel(self):
32+
def rel(self) -> str:
3333
""":return: the Link relation."""
3434
return self['rel']
3535

3636
@property
37-
def href(self):
37+
def href(self) -> str:
3838
""":return: the Link url."""
3939
return self['href']
4040

4141
@property
42-
def type(self):
42+
def type(self) -> str:
4343
""":return: the type of the Link object."""
4444
return self['type']
4545

4646
@property
47-
def title(self):
47+
def title(self) -> str:
4848
""":return: the title of the Link object."""
4949
return self['title']

0 commit comments

Comments
 (0)