GenSON icon indicating copy to clipboard operation
GenSON copied to clipboard

Change "required" field to be an optional field.

Open YehudaCorsia opened this issue 6 years ago • 8 comments

Hello, I am think that "required" field should be an optional.

Sometimes people don't want this field, and now they need to remove this field by themselves.

YehudaCorsia avatar May 06 '19 13:05 YehudaCorsia

I am think that all what we need to do for this issue is just add a conditional before This code.

and also change our testing and get this flag from user.

YehudaCorsia avatar May 06 '19 13:05 YehudaCorsia

Huh. I built this as an exploratory tool initially, so I just figured required would help you know more about the object. What's your use-case?

wolverdude avatar May 08 '19 04:05 wolverdude

Just chiming in here! First of all, thanks Jon for this tool. I've used it in anger more than once and now looking at enhancing it a bit. For now I went ahead and forked it for my particular use case, which is similar to what @YehudaCorsia is saying.

My idea initially (I've done a hard coded hack for now) was to base 'required', 'OneOf' and 'AllOf' on the values of the keys fed in to GenSON. True could mean it's required, False could mean not. A string value of 'required' would result in it being required. Where arrays of objects or scalars are concerned, a single instance with the aforementioned logic would result in a 'OneOf' and more than one 'AllOf'.

Just some thoughts for now, but wondered what your thoughts are. My particular use case is very specific and I would imagine not applicable to many (if not all). I'm generating canonical JSON examples from another schema format but want to use a JSON schema for web form and input validation. I can construct arbitrary JSON using the ideas in my comment resulting in GenSON adding in the required/OneOf/AllOf fields.

Let me know what you think. I'm happy to have a hack at this and see if I can make a prototype work.

Anyway. Thanks again for publishing this. It's been a real life saver this last couple of weeks.

davedotdev avatar May 22 '20 15:05 davedotdev

@davedotdev I think I see what you're doing here. Since you seem to be depending on a very specific structure, we could probably support your use-case with see-schemas.

Let's say you can pass required as True of False in a seed schema. The default for the Object strategy will still be True, but if you want it to default to False instead, we could make that easily overrideable with a custom strategy.

How does that sound?

wolverdude avatar May 22 '20 19:05 wolverdude

Thanks for coming back so quickly. Sounds interesting!

My hard coded hack checks for a specific property key and then from that point onwards, every object below that one is marked as not required. To make it more fun, that specific key might not always be present; the most reliable thing I could do is traverse three times and mark each node as required and then everything below those three as not required. That gets me to a good place. To add further complexity, some of my optional objects will be required and some not, hence my 'pie in the sky' thinking about burying some specific values which in turn governs the required nature for thoes keys. It would be fantastic to handle these conditions. If it doesn't make sense, I can generate some JSON and share if it would help?

davedotdev avatar May 22 '20 21:05 davedotdev

Not sure I fully understand, but it does sound like your use-case is too specific for any general solution. A hacked fork of the project may actually be the correct solution here.

wolverdude avatar May 22 '20 23:05 wolverdude

Same requirement. can we take this up

srmitharwal avatar Feb 25 '24 16:02 srmitharwal

If your goal is only to remove the required key, you should be able to do that fairly simply with a custom Object SchemaStrategy class.

Here's an example of how to do it. I ran the code to make sure it works, so you should be able to copy-paste it as-is:

from genson import SchemaBuilder
from genson.schema.strategies import Object

class NoRequiredObject(Object):
    KEYWORDS = tuple(kw for kw in Object.KEYWORDS if kw != 'required')

    # remove 'required' from the output if present
    def to_schema(self):
        schema = super().to_schema()
        if 'required' in schema:
            del schema['required']
        return schema

class NoRequiredSchemaBuilder(SchemaBuilder):
    """SchemaBuilder that does not use the 'required' keyword."""
    EXTRA_STRATEGIES = (NoRequiredObject,)

From there, just use NoRequiredSchemaBuilder wherever you would otherwise use SchemaBuilder.

wolverdude avatar Feb 25 '24 19:02 wolverdude