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

fix: make descriptions/examples available in JSON schema output #274

Closed
wants to merge 1 commit into from

Conversation

jsstevenson
Copy link
Contributor

@jsstevenson jsstevenson commented Oct 27, 2023

This PR makes two changes

  1. it provides the Code example within json_schema_extra rather than the example keyword. This resolves a small but annoying deprecation warning. It also requires ticking up the Pydantic pin that just got changed a few days ago, though.

  2. It handles descriptions in RootModels to ensure that they're included in the generated JSON schema output (as used by applications like FastAPI). Currently, we supply descriptions to primitive-y types like Condition and Code using the description keyword. Counterintuitively, that argument doesn't actually get used in the JSON schema output, as far as I can tell. Instead, Pydantic first checks if there's a description in the json_schema_extra arg, and if not, it just uses the class docstring (otherwise, no description).

The simple way out is to just take the description text and supply them as docstrings. This, however, includes a bunch of unsightly newlines and extra spaces. Alternatively, we could include descriptions a second time, but under json_schema_extra=, not description=.

from pprint import PrettyPrinter
from pydantic import BaseModel, RootModel, Field

class RootClassFirst(RootModel):
    """Docstring description"""
    root: str = Field(
        ...,
        description="Arg description",
        json_schema_extra={"description": "JSONschema description"}
    )

class RootClassSecond(RootModel):
    """Docstring description"""
    root: str = Field(..., description="Arg description")

class RootClassThird(RootModel):
    root: str = Field(..., description="Arg description")

class Container(BaseModel):
    one: RootClassFirst = Field(..., description="container arg description")
    two: RootClassSecond = Field(..., description="container arg description", json_schema_extra={"description": "container json schema description"})
    three: RootClassThird = Field(..., )
    four: RootClassSecond = Field(..., )


instance = Container(one="a", two="b", three="c", four="d")
ppr = PrettyPrinter(indent=2)
ppr.pprint(instance.model_json_schema())
[ 2-alpha ⚙ venv] ~/code/vrs-python % python3 scratch.py
{ '$defs': { 'RootClassFirst': { 'description': 'JSONschema description',
                                 'title': 'RootClassFirst',
                                 'type': 'string'},
             'RootClassSecond': { 'description': 'Docstring description',
                                  'title': 'RootClassSecond',
                                  'type': 'string'},
             'RootClassThird': {'title': 'RootClassThird', 'type': 'string'}},
  'properties': { 'four': {'$ref': '#/$defs/RootClassSecond'},
                  'one': { 'allOf': [{'$ref': '#/$defs/RootClassFirst'}],
                           'description': 'container arg description'},
                  'three': {'$ref': '#/$defs/RootClassThird'},
                  'two': { 'allOf': [{'$ref': '#/$defs/RootClassSecond'}],
                           'description': 'container json schema description'}},
  'required': ['one', 'two', 'three', 'four'],
  'title': 'Container',
  'type': 'object'}

@jsstevenson jsstevenson deleted the field-warning branch July 15, 2024 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant