Skip to content

Commit a78acb1

Browse files
committed
Drop unused functionality for function based converters
1 parent 951a0c1 commit a78acb1

File tree

8 files changed

+75
-167
lines changed

8 files changed

+75
-167
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1212
### Changed
1313

1414
- Improve Converter template.py usability
15+
- Remove functionality for function based converters
1516

1617
## [v0.10.0] - 2025-03-11
1718

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ Install the pre-commit hook with `pre-commit install`, so you never commit incor
189189

190190
The following high-level description gives an idea how to implement a converter in fiboa CLI:
191191

192-
1. Create a new file in `fiboa_cli/datasets` based on the `template.py`
193-
2. Implement the `convert()` function / test it / run it
192+
1. Create a new file in `fiboa_cli/datasets/your_file.py` based on the `template.py`
193+
2. Fill in the required variables / test it / run it
194194
3. Add missing dependencies into a separate dependency group in `setup.py`
195195
4. Add the converter to the list above
196196
5. Create a PR to submit your converter for review

fiboa_cli/__init__.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -525,11 +525,11 @@ def converters(providers, sources, verbose):
525525
"""
526526
log(f"fiboa CLI {__version__} - List of Converters\n", "success")
527527

528-
columns = {"SHORT_NAME": "Short Title", "LICENSE": "License"}
528+
columns = {"short_name": "Short Title", "license": "License"}
529529
if providers:
530-
columns["PROVIDERS"] = "Provider(s)"
530+
columns["providers"] = "Provider(s)"
531531
if sources:
532-
columns["SOURCES"] = "Source(s)"
532+
columns["sources"] = "Source(s)"
533533

534534
keys = list(columns.keys())
535535
converters = list_all_converters(keys)

fiboa_cli/convert.py

+16-27
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,15 @@ def list_all_converters(keys):
6262
obj = {}
6363
try:
6464
converter = read_converter(id)
65-
# todo remove this if once class-based converters have been fully implemented
66-
if isinstance(converter, BaseConverter):
67-
assert converter.__class__.__name__ != "TemplateConverter", (
68-
f"Please change TemplateConverter for {id}"
69-
)
7065

7166
for key in keys:
72-
# todo remove this if once class-based converters have been fully implemented
73-
if isinstance(converter, BaseConverter):
74-
value = getattr(converter, key.lower())
75-
else:
76-
value = getattr(converter, key, None)
67+
value = getattr(converter, key.lower())
7768

78-
if key == "SOURCES" and isinstance(value, dict):
69+
if key == "sources" and isinstance(value, dict):
7970
value = ", ".join(list(value.keys()))
80-
elif key == "LICENSE" and isinstance(value, dict):
71+
elif key == "license" and isinstance(value, dict):
8172
value = value["href"]
82-
elif key == "PROVIDERS" and isinstance(value, list):
73+
elif key == "providers" and isinstance(value, list):
8374
value = ", ".join(list(map(lambda x: x["name"], value)))
8475

8576
obj[key] = value
@@ -93,17 +84,15 @@ def list_all_converters(keys):
9384
def read_converter(_id):
9485
module_name = f".datasets.{_id}"
9586
module = importlib.import_module(module_name, package="fiboa_cli")
96-
# todo: remove conditional once class-based converters have been fully implemented
97-
if not hasattr(module, "convert"):
98-
try:
99-
clazz = next(
100-
v
101-
for v in module.__dict__.values()
102-
if type(v) is type
103-
and issubclass(v, BaseConverter)
104-
and "BaseConverter" not in v.__name__
105-
)
106-
return clazz()
107-
except StopIteration:
108-
log("Missing convert function or Converter class for module {_id}", "warning")
109-
return module
87+
try:
88+
clazz = next(
89+
v
90+
for v in module.__dict__.values()
91+
if type(v) is type
92+
and issubclass(v, BaseConverter)
93+
and "BaseConverter" not in v.__name__
94+
)
95+
return clazz()
96+
except StopIteration:
97+
log(f"Missing Converter class for module {_id}", "error")
98+
raise ImportError(f"Missing Converter class for module {_id}")

fiboa_cli/convert_utils.py

+1-76
Original file line numberDiff line numberDiff line change
@@ -28,73 +28,6 @@
2828
from .version import fiboa_version
2929

3030

31-
def convert(
32-
output_file,
33-
cache,
34-
urls,
35-
column_map,
36-
id,
37-
title,
38-
description,
39-
input_files=None,
40-
bbox=None,
41-
providers=[],
42-
source_coop_url=None,
43-
extensions=set(),
44-
missing_schemas={},
45-
column_additions={},
46-
column_filters={},
47-
column_migrations={},
48-
migration=None,
49-
file_migration=None,
50-
layer_filter=None,
51-
attribution=None,
52-
store_collection=False,
53-
license=None,
54-
compression=None,
55-
geoparquet1=False,
56-
original_geometries=False,
57-
index_as_id=False,
58-
year=None, # noqa unused
59-
**kwargs,
60-
):
61-
# this function is a (temporary) bridge from function-based converters to class-based converters
62-
# todo: this convert-function should be removed once class-based converters have been fully implemented
63-
64-
converter = BaseConverter(
65-
sources=urls,
66-
columns=column_map,
67-
id=id,
68-
title=title,
69-
description=description,
70-
bbox=bbox,
71-
providers=providers,
72-
short_name=id,
73-
extensions=extensions,
74-
missing_schemas=missing_schemas,
75-
column_additions=column_additions,
76-
column_filters=column_filters,
77-
column_migrations=column_migrations,
78-
migrate=migration,
79-
file_migration=file_migration,
80-
layer_filter=layer_filter,
81-
attribution=attribution,
82-
license=license,
83-
index_as_id=index_as_id,
84-
)
85-
converter.convert(
86-
output_file,
87-
cache,
88-
input_files=input_files,
89-
source_coop_url=source_coop_url,
90-
store_collection=store_collection,
91-
compression=compression,
92-
geoparquet1=geoparquet1,
93-
original_geometries=original_geometries,
94-
**kwargs,
95-
)
96-
97-
9831
def add_asset_to_collection(collection, output_file, rows=None, columns=None):
9932
c = collection.copy()
10033
if "assets" not in c or not isinstance(c["assets"], dict):
@@ -184,11 +117,7 @@ class BaseConverter:
184117

185118
index_as_id = False
186119

187-
def __init__(self, **kwargs):
188-
# This init method allows you to override all properties & methods
189-
# It's a bit hacky but allows a gradual conversion from function-based to class-based converters
190-
# todo remove this once class-based converters have been fully implemented
191-
self.__dict__.update({k: v for k, v in kwargs.items() if v is not None})
120+
def __init__(self):
192121
for key in ("id", "short_name", "title", "license", "columns"):
193122
assert getattr(self, key) is not None, (
194123
f"{inspect.getfile(self.__class__)}:{self.__class__.__name__} misses required attribute {key}"
@@ -200,10 +129,6 @@ def __init__(self, **kwargs):
200129
if not key.startswith("_") and isinstance(item, (list, dict, set)):
201130
setattr(self, key, copy(item))
202131

203-
@property
204-
def ID(self): # noqa backwards compatibility for function-based converters
205-
return self.id
206-
207132
def migrate(self, gdf) -> gpd.GeoDataFrame:
208133
return gdf
209134

fiboa_cli/datasets/commons/ec.py

+41-57
Original file line numberDiff line numberDiff line change
@@ -5,73 +5,57 @@
55

66
from fiboa_cli.util import load_file
77

8-
from .dictobject import DictObject
98

9+
class EuroCropsConverterMixin:
10+
license = "CC-BY-SA-4.0"
1011

11-
def add_eurocrops(base, year=None):
12-
if isinstance(base, dict):
13-
base = DictObject(base)
14-
15-
ID = base.ID
16-
if not base.ID.startswith("ec_"):
17-
ID = "ec_" + ID
18-
19-
SUFFIX = " - Eurocrops"
20-
if year is not None:
21-
SUFFIX += " " + str(year)
22-
23-
TITLE = base.TITLE + SUFFIX
24-
25-
SHORT_NAME = base.SHORT_NAME + SUFFIX
26-
27-
DESCRIPTION = (
28-
base.DESCRIPTION.strip()
29-
+ """
30-
31-
This dataset is an extended version of the original dataset, with additional columns and attributes added by the EuroCrops project.
32-
33-
The project developed a new **Hierarchical Crop and Agriculture Taxonomy (HCAT)** that harmonises all declared crops across the European Union.
34-
In the data you'll find this as additional attributes:
35-
36-
- `EC_trans_n`: The original crop name translated into English
37-
- `EC_hcat_n`: The machine-readable HCAT name of the crop
38-
- `EC_hcat_c`: The 10-digit HCAT code indicating the hierarchy of the crop
39-
"""
40-
)
12+
ec_mapping_csv = None
13+
mapping_file = None
14+
ec_mapping = None
4115

42-
PROVIDERS = base.PROVIDERS + [
43-
{"name": "EuroCrops", "url": "https://github.com/maja601/EuroCrops", "roles": ["processor"]}
44-
]
16+
def __init__(self, *args, year=None, **kwargs):
17+
super().__init__(*args, **kwargs)
18+
if not self.id.startswith("ec_"):
19+
self.id = "ec_" + self.id
4520

46-
EXTENSIONS = getattr(base, "EXTENSIONS", None) or set()
47-
EXTENSIONS.add("https://fiboa.github.io/hcat-extension/v0.1.0/schema.yaml")
48-
COLUMNS = base.COLUMNS | {
49-
"EC_trans_n": "ec:translated_name",
50-
"EC_hcat_n": "ec:hcat_name",
51-
"EC_hcat_c": "ec:hcat_code",
52-
}
21+
suffix = " - Eurocrops"
22+
if year is not None:
23+
suffix = f"{suffix} {year}"
5324

54-
LICENSE = "CC-BY-SA-4.0"
25+
self.title += suffix
26+
self.short_name += suffix
5527

56-
return ID, SHORT_NAME, TITLE, DESCRIPTION, PROVIDERS, EXTENSIONS, COLUMNS, LICENSE
28+
self.description = (
29+
self.description.strip()
30+
+ """
5731
32+
This dataset is an extended version of the original dataset, with additional columns and attributes added by the EuroCrops project.
5833
59-
class EuroCropsConverterMixin:
60-
ec_mapping_csv = None
61-
mapping_file = None
62-
ec_mapping = None
34+
The project developed a new **Hierarchical Crop and Agriculture Taxonomy (HCAT)** that harmonises all declared crops across the European Union.
35+
In the data you'll find this as additional attributes:
6336
64-
def __init__(self, *args, year=None, **kwargs):
65-
super().__init__(*args, **kwargs)
66-
# Some meta-magic to reuse existing add_eurocrops routine
67-
attributes = (
68-
"ID, SHORT_NAME, TITLE, DESCRIPTION, PROVIDERS, EXTENSIONS, COLUMNS, LICENSE".split(
69-
", "
70-
)
37+
- `EC_trans_n`: The original crop name translated into English
38+
- `EC_hcat_n`: The machine-readable HCAT name of the crop
39+
- `EC_hcat_c`: The 10-digit HCAT code indicating the hierarchy of the crop
40+
"""
7141
)
72-
base = {k: getattr(self, k.lower()) for k in attributes}
73-
for k, v in zip(attributes, add_eurocrops(base, year=year)):
74-
setattr(self, k.lower(), v)
42+
43+
self.providers += [
44+
{
45+
"name": "EuroCrops",
46+
"url": "https://github.com/maja601/EuroCrops",
47+
"roles": ["processor"],
48+
}
49+
]
50+
51+
self.extensions = getattr(self, "extensions", set())
52+
self.extensions.add("https://fiboa.github.io/hcat-extension/v0.1.0/schema.yaml")
53+
self.columns |= {
54+
"EC_trans_n": "ec:translated_name",
55+
"EC_hcat_n": "ec:hcat_name",
56+
"EC_hcat_c": "ec:hcat_code",
57+
}
58+
self.license = "CC-BY-SA-4.0"
7559

7660
def convert(self, *args, **kwargs):
7761
self.mapping_file = kwargs.get("mapping_file")

fiboa_cli/datasets/ec_lv.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ class Converter(EuroCropsConverterMixin, BaseConverter):
4242
"required": [
4343
"year",
4444
"parcel_id",
45-
"crop_id",
45+
"crop:code",
4646
"subsidy_type",
4747
"EC_NUTS3",
4848
# 'PRODUCT_DE',
4949
],
5050
"properties": {
5151
"year": {"type": "uint16", "minLength": 4, "maxLength": 4},
5252
"parcel_id": {"type": "uint64", "minLength": 8, "maxLength": 8},
53-
"crop_id": {"type": "uint16", "minLength": 3, "maxLength": 3},
53+
"crop:code": {"type": "uint16", "minLength": 3, "maxLength": 3},
5454
"subsidy_type": {"type": "string"},
5555
"EC_NUTS3": {
5656
"type": "string",
@@ -63,3 +63,7 @@ class Converter(EuroCropsConverterMixin, BaseConverter):
6363
# },
6464
},
6565
}
66+
67+
def add_hcat(self, gdf):
68+
# skip adding hcat
69+
return gdf

fiboa_cli/datasets/ec_si.py

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44

55
class Converter(EuroCropsConverterMixin, BaseConverter):
6+
ec_mapping_csv = "si_2021.csv"
67
sources = {
78
"https://zenodo.org/records/10118572/files/SI_2021.zip?download=1": ["SI_2021_EC21.shp"]
89
}
@@ -46,3 +47,7 @@ class Converter(EuroCropsConverterMixin, BaseConverter):
4647
"EC_NUTS3": {"type": "string"},
4748
},
4849
}
50+
51+
def add_hcat(self, gdf):
52+
# skip adding hcat
53+
return gdf

0 commit comments

Comments
 (0)