|
6 | 6 | import nob |
7 | 7 | import xmltodict |
8 | 8 | import yaml |
9 | | -from pydantic import BaseModel, ConfigDict, Field |
| 9 | +from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_validator |
10 | 10 |
|
11 | 11 | from dvuploader import File, add_directory |
12 | 12 |
|
13 | 13 | from easyDataverse.base import DataverseBase |
| 14 | +from easyDataverse.datasettype import DatasetType |
14 | 15 | from easyDataverse.license import CustomLicense, License |
15 | 16 | from easyDataverse.uploader import update_dataset, upload_to_dataverse |
16 | 17 | from easyDataverse.utils import YAMLDumper |
@@ -54,9 +55,51 @@ class Dataset(BaseModel): |
54 | 55 | description="The files of the dataset.", |
55 | 56 | ) |
56 | 57 |
|
| 58 | + dataset_type: Optional[str] = Field( |
| 59 | + default=None, |
| 60 | + description="The type of the dataset.", |
| 61 | + ) |
| 62 | + |
57 | 63 | API_TOKEN: Optional[str] = Field(None) |
58 | 64 | DATAVERSE_URL: Optional[str] = Field(None) |
59 | 65 |
|
| 66 | + # ! Validators |
| 67 | + @field_validator("dataset_type", mode="after") |
| 68 | + def _validate_dataset_type( |
| 69 | + cls, |
| 70 | + dataset_type: Optional[str], |
| 71 | + info: ValidationInfo, |
| 72 | + ) -> Optional[str]: |
| 73 | + """Validates the dataset type against available types in the Dataverse installation. |
| 74 | +
|
| 75 | + This validator ensures that the provided dataset type is valid and available |
| 76 | + in the target Dataverse installation. It fetches the available dataset types |
| 77 | + from the Dataverse instance and validates the provided type against them. |
| 78 | +
|
| 79 | + Note: |
| 80 | + If dataset_type is None, validation is skipped and None is returned. |
| 81 | + The DATAVERSE_URL must be set in the model for validation to work. |
| 82 | + """ |
| 83 | + if dataset_type is None: |
| 84 | + return dataset_type |
| 85 | + elif info.data["DATAVERSE_URL"] is None: |
| 86 | + raise ValueError( |
| 87 | + "No Dataverse URL has been provided. Please provide a Dataverse URL to validate the dataset type.", |
| 88 | + "This error should not happen and is likely a bug in the code.", |
| 89 | + "Please report this issue https://github.com/gdcc/easyDataverse/issues", |
| 90 | + ) |
| 91 | + |
| 92 | + available_types = DatasetType.from_instance(info.data["DATAVERSE_URL"]) # type: ignore |
| 93 | + available_names = [type.name for type in available_types] |
| 94 | + |
| 95 | + if dataset_type not in available_names: |
| 96 | + raise ValueError( |
| 97 | + f"Dataset type '{dataset_type}' is not available in the Dataverse installation. " |
| 98 | + f"Please use 'list_dataset_types' to see which dataset types are available." |
| 99 | + ) |
| 100 | + |
| 101 | + return dataset_type |
| 102 | + |
60 | 103 | # ! Adders |
61 | 104 | def add_metadatablock(self, metadatablock: DataverseBase) -> None: |
62 | 105 | """Adds a metadatablock object to the dataset if it is of 'DataverseBase' type and has a metadatablock name""" |
@@ -190,13 +233,24 @@ def dataverse_dict(self) -> dict: |
190 | 233 | else: |
191 | 234 | terms = {} |
192 | 235 |
|
| 236 | + dataset_type = self._get_dataset_type() |
| 237 | + |
193 | 238 | return { |
| 239 | + "datasetType": dataset_type, |
194 | 240 | "datasetVersion": { |
195 | 241 | "metadataBlocks": blocks, |
196 | 242 | **terms, |
197 | | - } |
| 243 | + }, |
198 | 244 | } |
199 | 245 |
|
| 246 | + def _get_dataset_type(self) -> str: |
| 247 | + """Returns the dataset type of the dataset.""" |
| 248 | + |
| 249 | + if self.dataset_type is None: |
| 250 | + return "dataset" |
| 251 | + |
| 252 | + return self.dataset_type |
| 253 | + |
200 | 254 | def dataverse_json(self, indent: int = 2) -> str: |
201 | 255 | """Returns a JSON representation of the dataverse dataset.""" |
202 | 256 |
|
|
0 commit comments