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 Schema with external $ref as a model #892

Closed
miniscruff opened this issue Oct 13, 2019 · 5 comments
Closed

JSON Schema with external $ref as a model #892

miniscruff opened this issue Oct 13, 2019 · 5 comments
Labels

Comments

@miniscruff
Copy link

Feature Request

I have begun to use pydantic models to create JSON schema files to publish and reference internally on my team. This has allowed us to create very easy to read python classes that create well-defined JSON schemas. The process has been really smooth so far and I am very grateful to all the work that has been put into this project.

My process is basically to create models, take the schema, wrap that schema with some extra metadata, create a JSON file and push it to one of our servers.

I have run into two, rather small, problems. ( I may create another issue for the second one later ) The first of which is the inability to reference external JSON schemas as a field. Such as one from here http://schemastore.org/json/.

An example test case would be:

def test_model_with_ref_only():
    class Dep(BaseModel):
        class Config:
            schema_ref = "http://example.com/schema.json"

    class Model(BaseModel):
        dep: Dep

    expected = {
        'title': 'Model',
        'type': 'object',
        'properties': {'dep': {'$ref': 'http://example.com/schema.json'}},
        'required': ['dep'],
    }

    assert Model.schema() == expected

Note that the model is not added as a definition as well as $ref being the only field.

And I am sure there are other alternatives that would solve this problem but I felt this matched the existing configurations well, but of course, if another approach or naming would make more sense let me know.

I have forked, branched and written the code to handle this test case but wanted to bring it up as an issue first. If this looks right to you I can make a pull request or wait for version 1.0.

@samuelcolvin
Copy link
Member

sorry for the slow response, not sure how this slipped through the gaps.

Couldn't this be done now with schema_extra? or by allowing function for schema_extra which allowed you to modify the schema?

That would seem like a more flexible solution.

@miniscruff
Copy link
Author

No problem, I thought I tried schema_extra before but I guess I didn't do a good job as it worked just fine today in the office.

It does create an extra model and includes the title and empty properties object but VS Code seems to deal with it fine and provides the help I expect.

class Dep(BaseModel):
        class Config:
            schema_extra = {
                "$ref": "http://example.com/schema.json",
            }

    class Model(BaseModel):
        dep: Dep

Is what I have and it works just fine. ( Although I just typed this out now so I will check when I go in tomorrow to make sure. )

@dmontagu
Copy link
Contributor

Just adding a note here for future reference if anyone tries to implement this -- it should probably be possible to make use of a classmethod to generate the schema to make it easier to inspect the actual class during schema generation.

@miniscruff
Copy link
Author

I will close this issue as it works as expected and what I would of done would just be a weird special case.

@mcgfeller
Copy link

Beware in Pydantic 2:

The $ref value must not be a str (leads to erros in JSON Schema generation in 2.5). It should be a jsonable non-str object. According to https://cswr.github.io/JsonSchema/spec/definitions_references/, it must be a JSON reference within the schema, or an URI. So you may use AnyUrl, which works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants