Skip to content

Commit e0e8f69

Browse files
committed
feat: update datacite model to version 4.6
I am not sure what the best way to deal with schema versions is. The easiest thing and the current strategy is to provide the latest versions that are backward-compatible with prior versions (within reason) i.e.: * `CodeMetaV3` can accept v2 fields and turn them into v3 equivalents * `DataCiteV46` implements the latest changes to v4, and does not break compatibility with any other v4 version Citation File Format provides jsonschema so in this case, it would be easy to provide seperate models
1 parent e97bb3d commit e0e8f69

File tree

5 files changed

+667
-10
lines changed

5 files changed

+667
-10
lines changed

codemeticulous/cff/models.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ class Reference(BaseModel):
15751575
"""
15761576

15771577

1578-
class CitationFileFormat(ByAliasExcludeNoneMixin, BaseModel):
1578+
class CitationFileFormatV120(ByAliasExcludeNoneMixin, BaseModel):
15791579
model_config = ConfigDict(
15801580
extra="forbid",
15811581
populate_by_name=True,
@@ -1694,3 +1694,6 @@ class CitationFileFormat(ByAliasExcludeNoneMixin, BaseModel):
16941694
"""
16951695
The version of the software or dataset.
16961696
"""
1697+
1698+
1699+
CitationFileFormat = CitationFileFormatV120

codemeticulous/codemeta/models.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class VersionedLanguage(ComputerLanguage):
4040
SoftwareListOrSingle = Software | SoftwareList
4141

4242

43-
class CodeMeta(ByAliasExcludeNoneMixin, BaseModel):
43+
class CodeMetaV3(ByAliasExcludeNoneMixin, BaseModel):
4444
"""CodeMeta v3 schema (supports v2 fields aliased to v3)
4545
see: https://codemeta.github.io/terms/
4646
and: https://github.com/codemeta/codemeta-generator/blob/master/js/validation/
@@ -272,3 +272,6 @@ def validate_sub_type(cls, value, base_class):
272272

273273
class Config:
274274
allow_population_by_field_name = True
275+
276+
277+
CodeMeta = CodeMetaV3

codemeticulous/datacite/convert.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
"financial backer",
155155
},
156156
ContributorType.Supervisor: {"supervisor", "advisor", "overseer", "mentor"},
157+
ContributorType.Translator: { "translator", "translation" },
157158
ContributorType.WorkPackageLeader: {
158159
"work package leader",
159160
"package leader",
@@ -222,9 +223,17 @@ def codemeta_actors_to_datacite(
222223
# match roles to contributor types
223224
matched_roles = set()
224225
for role in extractor.role_names:
225-
normalized_role = role.lower().replace(" ", "").replace("-", "").replace("_", "")
226-
for contributor_type, synonyms, in CONTRIBUTOR_TYPE_MAP.items():
227-
if normalized_role in {s.lower().replace(" ", "").replace("-", "").replace("_", "") for s in synonyms}:
226+
normalized_role = (
227+
role.lower().replace(" ", "").replace("-", "").replace("_", "")
228+
)
229+
for (
230+
contributor_type,
231+
synonyms,
232+
) in CONTRIBUTOR_TYPE_MAP.items():
233+
if normalized_role in {
234+
s.lower().replace(" ", "").replace("-", "").replace("_", "")
235+
for s in synonyms
236+
}:
228237
matched_roles.add(contributor_type)
229238
# if we have no matched roles, default to "Other"
230239
if not matched_roles:
@@ -235,13 +244,16 @@ def codemeta_actors_to_datacite(
235244
Contributor(
236245
name=extractor.name,
237246
nameType=(
238-
"Organizational" if extractor.is_organization else "Personal"
247+
"Organizational"
248+
if extractor.is_organization
249+
else "Personal"
239250
),
240251
givenName=extractor.given_names,
241252
familyName=extractor.family_names,
242253
nameIdentifiers=[NameIdentifier(**i) for i in name_identifiers]
243254
or None,
244-
affiliation=[AffiliationItem(**a) for a in affiliations] or None,
255+
affiliation=[AffiliationItem(**a) for a in affiliations]
256+
or None,
245257
contributorType=role_type.value,
246258
)
247259
)

codemeticulous/datacite/models.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
generated by datamodel-codegen (schema/datacite/schema45.json)
2+
generated by datamodel-codegen (schema/datacite/schema46.json)
33
with options:
44
--output-model-type pydantic_v2.BaseModel \
55
--field-constraints \
@@ -13,7 +13,7 @@
1313
MANUAL CHANGES:
1414
- add ByAliasExcludeNoneMixin to DataciteV45
1515
- add identifier and identifierType to Container, this is included in examples
16-
for schema 4.5 but not in the schema itself..
16+
but not in the source jsonschema
1717
"""
1818

1919
from __future__ import annotations
@@ -163,6 +163,7 @@ class ContributorType(Enum):
163163
RightsHolder = "RightsHolder"
164164
Sponsor = "Sponsor"
165165
Supervisor = "Supervisor"
166+
Translator = "Translator"
166167
WorkPackageLeader = "WorkPackageLeader"
167168
Other = "Other"
168169

@@ -179,6 +180,7 @@ class DateType(Enum):
179180
Available = "Available"
180181
Copyrighted = "Copyrighted"
181182
Collected = "Collected"
183+
Coverage = "Coverage"
182184
Created = "Created"
183185
Issued = "Issued"
184186
Submitted = "Submitted"
@@ -190,6 +192,7 @@ class DateType(Enum):
190192

191193
class ResourceTypeGeneral(Enum):
192194
Audiovisual = "Audiovisual"
195+
Award = "Award"
193196
Book = "Book"
194197
BookChapter = "BookChapter"
195198
Collection = "Collection"
@@ -210,6 +213,7 @@ class ResourceTypeGeneral(Enum):
210213
PeerReview = "PeerReview"
211214
PhysicalObject = "PhysicalObject"
212215
Preprint = "Preprint"
216+
Project = "Project"
213217
Report = "Report"
214218
Service = "Service"
215219
Software = "Software"
@@ -225,6 +229,7 @@ class RelatedIdentifierType(Enum):
225229
ARK = "ARK"
226230
arXiv = "arXiv"
227231
bibcode = "bibcode"
232+
CTSR = "CTSR"
228233
DOI = "DOI"
229234
EAN13 = "EAN13"
230235
EISSN = "EISSN"
@@ -237,6 +242,7 @@ class RelatedIdentifierType(Enum):
237242
LSID = "LSID"
238243
PMID = "PMID"
239244
PURL = "PURL"
245+
RRID = "RRID"
240246
UPC = "UPC"
241247
URL = "URL"
242248
URN = "URN"
@@ -280,6 +286,8 @@ class RelationType(Enum):
280286
Requires = "Requires"
281287
IsObsoletedBy = "IsObsoletedBy"
282288
Obsoletes = "Obsoletes"
289+
isTranslationOf = "isTranslationOf"
290+
hasTranslation = "hasTranslation"
283291

284292

285293
class RelatedObject(BaseModel):
@@ -469,7 +477,7 @@ class RelatedItem(RelatedObject):
469477
relationType: RelationType
470478

471479

472-
class DataciteV45(ByAliasExcludeNoneMixin, BaseModel):
480+
class DataciteV46(ByAliasExcludeNoneMixin, BaseModel):
473481
model_config = ConfigDict(
474482
extra="forbid",
475483
populate_by_name=True,
@@ -502,3 +510,6 @@ class DataciteV45(ByAliasExcludeNoneMixin, BaseModel):
502510
"http://datacite.org/schema/kernel-4"
503511
)
504512
container: Optional[Container] = None
513+
514+
515+
DataCite = DataciteV46

0 commit comments

Comments
 (0)