Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON editor JSONSchema validation #4012

Merged
merged 8 commits into from
Nov 27, 2024

Conversation

jm-amt
Copy link
Contributor

@jm-amt jm-amt commented Nov 19, 2024

Added JSONSchema validation to json_editor.

New method json_editor.add_validation(schema) will enable validation on the json_editor component.


Feature request: #4003

@falkoschindler
Copy link
Contributor

Thanks for the pull request, @jm-amt!
Can you give an example how to use it? It tried ui.json_editor({'content': {'json': json}}, add_validation=schema) with json and schema from https://json-schema.org/learn/getting-started-step-by-step, but there doesn't seem to be any validation happening.

@falkoschindler falkoschindler added the enhancement New feature or request label Nov 21, 2024
@jm-amt
Copy link
Contributor Author

jm-amt commented Nov 24, 2024

I assume the issue will be the schema version from the example.
"$schema": "https://json-schema.org/draft/2020-12/schema", is not available with the validator version the json_editor uses.
I am now logging the specific error when it fails to construct the validator. You can check the browser console logs and will probably see no schema with key or ref "https://json-schema.org/draft/2020-12/schema".

Try just remove the $schema line (or change to an earlier draft) from your test code and see if that fixes it. Otherwise try this example (just one of the ones from the jsonschema docs you sent but I removed the $schema key.

from nicegui import ui

schema = {
    "$id": "https://example.com/product.schema.json",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
        "productId": {
            "description": "The unique identifier for a product",
            "type": "integer"
        },
        "productName": {
            "description": "Name of the product",
            "type": "string"
        },
        "price": {
            "description": "The price of the product",
            "type": "number",
            "exclusiveMinimum": 0
        }
    },
    "required": ["productId", "productName", "price"]
}


@ui.page("/")
async def index():
    data = {
        "productId": "10",  # String not number
        "productName": "Test Product", 
        "price": -1.01  # needs to be positive
    }
    ui.json_editor({"content": {"json": data}}, add_validation=schema)


ui.run()

@falkoschindler
Copy link
Contributor

Thanks for the update, @jm-amt!

So a minimum working example is like this:

@ui.page('/')
def index():
    ui.json_editor({'content': {'json': {'number': 'nan'}}},
                   add_validation={'type': 'object', 'properties': {'number': {'type': 'integer'}}})

Unfortunately it doesn't work on the auto-index page (without the @page decorator), probably because the event loop isn't running yet and run_method returns without doing anything.

I wonder if we can simplify the approach and pass the schema via the _props dictionary

self._props['schema'] = schema

with schema being the renamed add_validation parameter. This way we wouldn't need the add_validation method at all. Or do you think the user should be able to change the schema later?

@jm-amt
Copy link
Contributor Author

jm-amt commented Nov 26, 2024

I cannot say I had ever used auto indexing.

I think your idea of going through props is a much better idea. I removed the add_validation method and replaced it with the schema argument when creating the editor. You can update the schema later by modifying the underlying _props and calling json_editor.update()

This would now be a minimum working example (auto index page issue has been fixed):

ui.json_editor({'content': {'json': {'number': 'nan'}}}, schema={'type': 'object', 'properties': {'number': {'type': 'integer'}}})

Copy link
Contributor

@falkoschindler falkoschindler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, @jm-amt!
I just added a demo for the documentation and a simply pytest.
Let's merge! 🚀

@falkoschindler falkoschindler added this to the 2.8 milestone Nov 27, 2024
@falkoschindler falkoschindler merged commit f6e1377 into zauberzeug:main Nov 27, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants