configpanel: add proper schema definition

This commit is contained in:
axolotle 2023-10-25 15:07:31 +02:00
parent c4c79c61fe
commit 3faa574267
3 changed files with 47 additions and 4 deletions

View file

@ -0,0 +1,4 @@
from yunohost.utils.configpanel import ConfigPanelModel
print(ConfigPanelModel.schema_json(indent=2))

View file

@ -88,6 +88,14 @@ class SectionModel(ContainerModel, OptionsModel):
optional: bool = True optional: bool = True
is_action_section: bool = False is_action_section: bool = False
class Config:
@staticmethod
def schema_extra(schema: dict[str, Any]) -> None:
del schema["properties"]["id"]
options = schema["properties"].pop("options")
del schema["required"]
schema["additionalProperties"] = options["items"]
# Don't forget to pass arguments to super init # Don't forget to pass arguments to super init
def __init__( def __init__(
self, self,
@ -137,6 +145,13 @@ class PanelModel(ContainerModel):
class Config: class Config:
extra = Extra.allow extra = Extra.allow
@staticmethod
def schema_extra(schema: dict[str, Any]) -> None:
del schema["properties"]["id"]
del schema["properties"]["sections"]
del schema["required"]
schema["additionalProperties"] = {"$ref": "#/definitions/SectionModel"}
# Don't forget to pass arguments to super init # Don't forget to pass arguments to super init
def __init__( def __init__(
self, self,
@ -170,6 +185,26 @@ class ConfigPanelModel(BaseModel):
arbitrary_types_allowed = True arbitrary_types_allowed = True
extra = Extra.allow extra = Extra.allow
@staticmethod
def schema_extra(schema: dict[str, Any]) -> None:
"""Update the schema to the expected input
In actual TOML definition, schema is like:
```toml
[panel_1]
[panel_1.section_1]
[panel_1.section_1.option_1]
```
Which is equivalent to `{"panel_1": {"section_1": {"option_1": {}}}}`
so `section_id` (and `option_id`) are additional property of `panel_id`,
which is convinient to write but not ideal to iterate.
In ConfigPanelModel we gather additional properties of panels, sections
and options as lists so that structure looks like:
`{"panels`: [{"id": "panel_1", "sections": [{"id": "section_1", "options": [{"id": "option_1"}]}]}]
"""
del schema["properties"]["panels"]
del schema["required"]
schema["additionalProperties"] = {"$ref": "#/definitions/PanelModel"}
# Don't forget to pass arguments to super init # Don't forget to pass arguments to super init
def __init__( def __init__(
self, self,

View file

@ -319,10 +319,14 @@ class BaseOption(BaseModel):
extra = Extra.forbid extra = Extra.forbid
@staticmethod @staticmethod
def schema_extra(schema: dict[str, Any], model: Type["BaseOption"]) -> None: def schema_extra(schema: dict[str, Any]) -> None:
# FIXME Do proper doctstring for Options del schema["properties"]["id"]
del schema["description"] del schema["properties"]["name"]
schema["additionalProperties"] = False schema["required"] = [
required for required in schema.get("required", []) if required != "id"
]
if not schema["required"]:
del schema["required"]
@validator("id", pre=True) @validator("id", pre=True)
def check_id_is_not_forbidden(cls, value: str) -> str: def check_id_is_not_forbidden(cls, value: str) -> str: