mirror of https://github.com/eyhc1/rendercv.git
change data model design for a better JSON schema
This commit is contained in:
parent
e176f1bf36
commit
3070092a2b
|
@ -323,7 +323,7 @@ def generate_json_schema(output_directory: str) -> str:
|
|||
|
||||
|
||||
# ======================================================================================
|
||||
# CUSTOM DATA TYPES ====================================================================
|
||||
# DESIGN MODELS ========================================================================
|
||||
# ======================================================================================
|
||||
|
||||
# To understand how to create custom data types, see:
|
||||
|
@ -337,14 +337,6 @@ LaTeXDimension = Annotated[
|
|||
LaTeXString = Annotated[str, AfterValidator(escape_latex_characters)]
|
||||
SpellCheckedString = Annotated[LaTeXString, AfterValidator(check_spelling)]
|
||||
|
||||
# ======================================================================================
|
||||
# ======================================================================================
|
||||
# ======================================================================================
|
||||
|
||||
# ======================================================================================
|
||||
# DESIGN MODELS ========================================================================
|
||||
# ======================================================================================
|
||||
|
||||
|
||||
class ClassicThemePageMargins(BaseModel):
|
||||
"""This class stores the margins of pages for the classic theme."""
|
||||
|
@ -1034,24 +1026,20 @@ class Connection(BaseModel):
|
|||
return url
|
||||
|
||||
|
||||
class Section(BaseModel):
|
||||
"""This class stores a section information."""
|
||||
class SectionBase(BaseModel):
|
||||
"""This class stores a section information.
|
||||
|
||||
It is the parent class of all the section classes like
|
||||
`#!python SectionWithEducationEntries`, `#!python SectionWithExperienceEntries`,
|
||||
`#!python SectionWithNormalEntries`, `#!python SectionWithOneLineEntries`, and
|
||||
`#!python SectionWithPublicationEntries`.
|
||||
"""
|
||||
|
||||
title: LaTeXString = Field(
|
||||
title="Section Title",
|
||||
description="The title of the section.",
|
||||
examples=["My Custom Section"],
|
||||
)
|
||||
entry_type: Literal[
|
||||
"OneLineEntry",
|
||||
"NormalEntry",
|
||||
"ExperienceEntry",
|
||||
"EducationEntry",
|
||||
"PublicationEntry",
|
||||
] = Field(
|
||||
title="Entry Type",
|
||||
description="The type of the entries in the section.",
|
||||
)
|
||||
link_text: Optional[LaTeXString] = Field(
|
||||
default=None,
|
||||
title="Link Text",
|
||||
|
@ -1062,12 +1050,6 @@ class Section(BaseModel):
|
|||
),
|
||||
examples=["view on GitHub", "view on LinkedIn"],
|
||||
)
|
||||
entries: list[
|
||||
OneLineEntry | NormalEntry | ExperienceEntry | EducationEntry | PublicationEntry
|
||||
] = Field(
|
||||
title="Entries",
|
||||
description="The entries of the section. The format depends on the entry type.",
|
||||
)
|
||||
|
||||
@field_validator("title")
|
||||
@classmethod
|
||||
|
@ -1076,6 +1058,73 @@ class Section(BaseModel):
|
|||
return title.title()
|
||||
|
||||
|
||||
entry_type_field = Field(
|
||||
title="Entry Type",
|
||||
description="The type of the entries in the section.",
|
||||
)
|
||||
entries_field = Field(
|
||||
title="Entries",
|
||||
description="The entries of the section. The format depends on the entry type.",
|
||||
)
|
||||
|
||||
|
||||
class SectionWithEducationEntries(SectionBase):
|
||||
"""This class stores a section with
|
||||
[EducationEntry](../user_guide.md#educationentry)s.
|
||||
"""
|
||||
|
||||
entry_type: Literal["EducationEntry"] = entry_type_field
|
||||
entries: list[EducationEntry] = entries_field
|
||||
|
||||
|
||||
class SectionWithExperienceEntries(SectionBase):
|
||||
"""This class stores a section with
|
||||
[ExperienceEntry](../user_guide.md#experienceentry)s.
|
||||
"""
|
||||
|
||||
entry_type: Literal["ExperienceEntry"] = entry_type_field
|
||||
entries: list[ExperienceEntry] = entries_field
|
||||
|
||||
|
||||
class SectionWithNormalEntries(SectionBase):
|
||||
"""This class stores a section with
|
||||
[NormalEntry](../user_guide.md#normalentry)s.
|
||||
"""
|
||||
|
||||
entry_type: Literal["NormalEntry"] = entry_type_field
|
||||
entries: list[NormalEntry] = entries_field
|
||||
|
||||
|
||||
class SectionWithOneLineEntries(SectionBase):
|
||||
"""This class stores a section with
|
||||
[OneLineEntry](../user_guide.md#onelineentry)s.
|
||||
"""
|
||||
|
||||
entry_type: Literal["OneLineEntry"] = entry_type_field
|
||||
entries: list[OneLineEntry] = entries_field
|
||||
|
||||
|
||||
class SectionWithPublicationEntries(SectionBase):
|
||||
"""This class stores a section with
|
||||
[PublicationEntry](../user_guide.md#publicationentry)s.
|
||||
"""
|
||||
|
||||
entry_type: Literal["PublicationEntry"] = entry_type_field
|
||||
entries: list[PublicationEntry] = entries_field
|
||||
|
||||
|
||||
Section = Annotated[
|
||||
SectionWithEducationEntries
|
||||
| SectionWithExperienceEntries
|
||||
| SectionWithNormalEntries
|
||||
| SectionWithOneLineEntries
|
||||
| SectionWithPublicationEntries,
|
||||
Field(
|
||||
discriminator="entry_type",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
class CurriculumVitae(BaseModel):
|
||||
"""This class bindes all the information of a CV together."""
|
||||
|
||||
|
@ -1284,7 +1333,7 @@ class CurriculumVitae(BaseModel):
|
|||
|
||||
@computed_field
|
||||
@cached_property
|
||||
def sections(self) -> list[Section]:
|
||||
def sections(self) -> list[SectionBase]:
|
||||
sections = []
|
||||
|
||||
# Pre-defined sections (i.e. sections that are not custom)):
|
||||
|
@ -1368,7 +1417,15 @@ class CurriculumVitae(BaseModel):
|
|||
" order 😷"
|
||||
)
|
||||
|
||||
section = Section(
|
||||
object_map = {
|
||||
"EducationEntry": SectionWithEducationEntries,
|
||||
"ExperienceEntry": SectionWithExperienceEntries,
|
||||
"NormalEntry": SectionWithNormalEntries,
|
||||
"OneLineEntry": SectionWithOneLineEntries,
|
||||
"PublicationEntry": SectionWithPublicationEntries,
|
||||
}
|
||||
|
||||
section = object_map[entry_type](
|
||||
title=section_name,
|
||||
entry_type=entry_type, # type: ignore
|
||||
entries=entries,
|
||||
|
|
255
schema.json
255
schema.json
|
@ -534,7 +534,33 @@
|
|||
"allOf": [
|
||||
{
|
||||
"items": {
|
||||
"$ref": "#/$defs/Section"
|
||||
"discriminator": {
|
||||
"mapping": {
|
||||
"EducationEntry": "#/$defs/SectionWithEducationEntries",
|
||||
"ExperienceEntry": "#/$defs/SectionWithExperienceEntries",
|
||||
"NormalEntry": "#/$defs/SectionWithNormalEntries",
|
||||
"OneLineEntry": "#/$defs/SectionWithOneLineEntries",
|
||||
"PublicationEntry": "#/$defs/SectionWithPublicationEntries"
|
||||
},
|
||||
"propertyName": "entry_type"
|
||||
},
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/$defs/SectionWithEducationEntries"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/SectionWithExperienceEntries"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/SectionWithNormalEntries"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/SectionWithOneLineEntries"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/SectionWithPublicationEntries"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
|
@ -1263,7 +1289,7 @@
|
|||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Section": {
|
||||
"SectionWithEducationEntries": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"description": "The title of the section.",
|
||||
|
@ -1273,18 +1299,6 @@
|
|||
"title": "Section Title",
|
||||
"type": "string"
|
||||
},
|
||||
"entry_type": {
|
||||
"description": "The type of the entries in the section.",
|
||||
"enum": [
|
||||
"OneLineEntry",
|
||||
"NormalEntry",
|
||||
"ExperienceEntry",
|
||||
"EducationEntry",
|
||||
"PublicationEntry"
|
||||
],
|
||||
"title": "Entry Type",
|
||||
"type": "string"
|
||||
},
|
||||
"link_text": {
|
||||
"default": null,
|
||||
"description": "If the section has a link, then what should be the text of the link? If this field is not provided, then the link text will be generated automatically based on the URL.",
|
||||
|
@ -1299,26 +1313,15 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"entry_type": {
|
||||
"const": "EducationEntry",
|
||||
"description": "The type of the entries in the section.",
|
||||
"title": "Entry Type"
|
||||
},
|
||||
"entries": {
|
||||
"description": "The entries of the section. The format depends on the entry type.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/$defs/OneLineEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/NormalEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/ExperienceEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/EducationEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/PublicationEntry"
|
||||
}
|
||||
]
|
||||
"$ref": "#/$defs/EducationEntry"
|
||||
},
|
||||
"title": "Entries",
|
||||
"type": "array"
|
||||
|
@ -1329,7 +1332,195 @@
|
|||
"entry_type",
|
||||
"entries"
|
||||
],
|
||||
"title": "Section",
|
||||
"title": "SectionWithEducationEntries",
|
||||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"SectionWithExperienceEntries": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"description": "The title of the section.",
|
||||
"examples": [
|
||||
"My Custom Section"
|
||||
],
|
||||
"title": "Section Title",
|
||||
"type": "string"
|
||||
},
|
||||
"link_text": {
|
||||
"default": null,
|
||||
"description": "If the section has a link, then what should be the text of the link? If this field is not provided, then the link text will be generated automatically based on the URL.",
|
||||
"examples": [
|
||||
"view on GitHub",
|
||||
"view on LinkedIn"
|
||||
],
|
||||
"title": "Link Text",
|
||||
"allOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"entry_type": {
|
||||
"const": "ExperienceEntry",
|
||||
"description": "The type of the entries in the section.",
|
||||
"title": "Entry Type"
|
||||
},
|
||||
"entries": {
|
||||
"description": "The entries of the section. The format depends on the entry type.",
|
||||
"items": {
|
||||
"$ref": "#/$defs/ExperienceEntry"
|
||||
},
|
||||
"title": "Entries",
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"title",
|
||||
"entry_type",
|
||||
"entries"
|
||||
],
|
||||
"title": "SectionWithExperienceEntries",
|
||||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"SectionWithNormalEntries": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"description": "The title of the section.",
|
||||
"examples": [
|
||||
"My Custom Section"
|
||||
],
|
||||
"title": "Section Title",
|
||||
"type": "string"
|
||||
},
|
||||
"link_text": {
|
||||
"default": null,
|
||||
"description": "If the section has a link, then what should be the text of the link? If this field is not provided, then the link text will be generated automatically based on the URL.",
|
||||
"examples": [
|
||||
"view on GitHub",
|
||||
"view on LinkedIn"
|
||||
],
|
||||
"title": "Link Text",
|
||||
"allOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"entry_type": {
|
||||
"const": "NormalEntry",
|
||||
"description": "The type of the entries in the section.",
|
||||
"title": "Entry Type"
|
||||
},
|
||||
"entries": {
|
||||
"description": "The entries of the section. The format depends on the entry type.",
|
||||
"items": {
|
||||
"$ref": "#/$defs/NormalEntry"
|
||||
},
|
||||
"title": "Entries",
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"title",
|
||||
"entry_type",
|
||||
"entries"
|
||||
],
|
||||
"title": "SectionWithNormalEntries",
|
||||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"SectionWithOneLineEntries": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"description": "The title of the section.",
|
||||
"examples": [
|
||||
"My Custom Section"
|
||||
],
|
||||
"title": "Section Title",
|
||||
"type": "string"
|
||||
},
|
||||
"link_text": {
|
||||
"default": null,
|
||||
"description": "If the section has a link, then what should be the text of the link? If this field is not provided, then the link text will be generated automatically based on the URL.",
|
||||
"examples": [
|
||||
"view on GitHub",
|
||||
"view on LinkedIn"
|
||||
],
|
||||
"title": "Link Text",
|
||||
"allOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"entry_type": {
|
||||
"const": "OneLineEntry",
|
||||
"description": "The type of the entries in the section.",
|
||||
"title": "Entry Type"
|
||||
},
|
||||
"entries": {
|
||||
"description": "The entries of the section. The format depends on the entry type.",
|
||||
"items": {
|
||||
"$ref": "#/$defs/OneLineEntry"
|
||||
},
|
||||
"title": "Entries",
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"title",
|
||||
"entry_type",
|
||||
"entries"
|
||||
],
|
||||
"title": "SectionWithOneLineEntries",
|
||||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"SectionWithPublicationEntries": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"description": "The title of the section.",
|
||||
"examples": [
|
||||
"My Custom Section"
|
||||
],
|
||||
"title": "Section Title",
|
||||
"type": "string"
|
||||
},
|
||||
"link_text": {
|
||||
"default": null,
|
||||
"description": "If the section has a link, then what should be the text of the link? If this field is not provided, then the link text will be generated automatically based on the URL.",
|
||||
"examples": [
|
||||
"view on GitHub",
|
||||
"view on LinkedIn"
|
||||
],
|
||||
"title": "Link Text",
|
||||
"allOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"entry_type": {
|
||||
"const": "PublicationEntry",
|
||||
"description": "The type of the entries in the section.",
|
||||
"title": "Entry Type"
|
||||
},
|
||||
"entries": {
|
||||
"description": "The entries of the section. The format depends on the entry type.",
|
||||
"items": {
|
||||
"$ref": "#/$defs/PublicationEntry"
|
||||
},
|
||||
"title": "Entries",
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"title",
|
||||
"entry_type",
|
||||
"entries"
|
||||
],
|
||||
"title": "SectionWithPublicationEntries",
|
||||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue