Repository: IAMconsortium/nomenclature

Issue:
Add CLI option to run workflow file from command line 
For a lot of local upload trouble shooting it would be nice to run something along the lines of:

```console
nomenclature run_workflow input_data.xlsx
```
 
`run_workflow` would default to importing `workflow.py` from the current working directory and run the function `main` from `workflow.py`

Discussion:

Patch:
diff --git a/docs/user_guide/config.rst b/docs/user_guide/config.rst
index 9da5cd7..f9fd887 100644
--- a/docs/user_guide/config.rst
+++ b/docs/user_guide/config.rst
@@ -77,3 +77,19 @@ By setting *definitions.region.country* as *true* in the configuration file:
 the nomenclature package will add all countries to the *region* codelist.
 
 More details on the list of countries can be found here: :ref:`countries`.
+
+Specify dimensions to be read
+-----------------------------
+
+The configuration file offers the possibility to set the dimensions which will be read
+by *DataStructureDefinition*.
+
+In the below case we specify *region*, *variable* and *scenario* to be read and used for
+validation:
+
+.. code:: yaml
+
+  dimensions:
+    - region
+    - variable
+    - scenario
diff --git a/nomenclature/config.py b/nomenclature/config.py
index c037274..dabb080 100644
--- a/nomenclature/config.py
+++ b/nomenclature/config.py
@@ -1,3 +1,4 @@
+from enum import Enum
 from pathlib import Path
 from typing import Annotated, Optional
 
@@ -132,7 +133,16 @@ class RegionMappingConfig(BaseModel):
     model_config = ConfigDict(populate_by_name=True)
 
 
+class DimensionEnum(str, Enum):
+    model = "model"
+    scenario = "scenario"
+    variable = "variable"
+    region = "region"
+    subannual = "subannual"
+
+
 class NomenclatureConfig(BaseModel):
+    dimensions: None | list[DimensionEnum] = None
     repositories: dict[str, Repository] = Field(default_factory=dict)
     definitions: DataStructureConfig = Field(default_factory=DataStructureConfig)
     mappings: RegionMappingConfig = Field(default_factory=RegionMappingConfig)
diff --git a/nomenclature/definition.py b/nomenclature/definition.py
index 2c2cfff..d66330f 100644
--- a/nomenclature/definition.py
+++ b/nomenclature/definition.py
@@ -61,7 +61,14 @@ class DataStructureDefinition:
         ):
             raise NotADirectoryError(f"Definitions directory not found: {path}")
 
-        self.dimensions = dimensions or ["region", "variable"]
+        self.dimensions = (
+            dimensions
+            or self.config.dimensions
+            or [
+                "region",
+                "variable",
+            ]
+        )
         for dim in self.dimensions:
             codelist_cls = SPECIAL_CODELIST.get(dim, CodeList)
             self.__setattr__(


Test patch:
diff --git a/tests/data/general-config-only-country/nomenclature.yaml b/tests/data/general-config-only-country/nomenclature.yaml
index 5217775..7616a4d 100644
--- a/tests/data/general-config-only-country/nomenclature.yaml
+++ b/tests/data/general-config-only-country/nomenclature.yaml
@@ -1,3 +1,5 @@
+dimensions:
+  - region
 definitions:
   region:
     country: true
diff --git a/tests/data/nomenclature_configs/dimensions.yaml b/tests/data/nomenclature_configs/dimensions.yaml
new file mode 100644
index 0000000..a7f63f9
--- /dev/null
+++ b/tests/data/nomenclature_configs/dimensions.yaml
@@ -0,0 +1,4 @@
+dimensions:
+   - region
+   - variable
+   - scenario
diff --git a/tests/test_config.py b/tests/test_config.py
index 9674f08..7670424 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -67,3 +67,25 @@ def test_double_stacked_external_repo_raises(monkeypatch):
     match = "External repos cannot again refer to external repos"
     with raises(ValueError, match=match):
         repo.check_external_repo_double_stacking()
+
+
+def test_config_dimensions():
+    config = NomenclatureConfig.from_file(
+        TEST_DATA_DIR / "nomenclature_configs" / "dimensions.yaml"
+    )
+    assert set(config.dimensions) == {
+        "scenario",
+        "region",
+        "variable",
+    }
+
+
+def test_invalid_config_dimensions_raises():
+    with raises(
+        ValueError,
+        match=(
+            "Input should be 'model', 'scenario', 'variable',"
+            " 'region' or 'subannual'"
+        ),
+    ):
+        NomenclatureConfig(dimensions=["year"])
diff --git a/tests/test_definition.py b/tests/test_definition.py
index b6e1c97..5db1986 100644
--- a/tests/test_definition.py
+++ b/tests/test_definition.py
@@ -66,8 +66,7 @@ def test_definition_from_general_config(workflow_folder):
 
 def test_definition_general_config_country_only():
     obs = DataStructureDefinition(
-        TEST_DATA_DIR / "general-config-only-country" / "definitions",
-        dimensions=["region"],
+        TEST_DATA_DIR / "general-config-only-country" / "definitions"
     )
     assert all(region in obs.region for region in ("Austria", "Bolivia", "Kosovo"))