[Python] Resolving $ref $defs to get properties from Pydantic model_jason_schema

Discussão em 'Python' iniciado por Stack, Junho 2, 2025.

  1. Stack

    Stack Membro Participativo

    I'm using a library that utilizes Pydantic v2 and .model_json_schema()['properties'] to pull information and metadata about the class properties (like those set by Field json_schema_extra). I've found the library fails when you build a class with an optional self reference because ['properties'] in the json schema becomes a key within the '#/$defs/' dictionary, pointed to by $ref.

    Is the following function the most efficient/direct way to pull the ['properties'] dictionary from the Pydantic class?

    def resolve_ref(schema, ref_value):
    """
    Resolves a JSON Schema $ref to a definition within the same schema.

    Args:
    schema (dict): The JSON Schema dictionary.
    ref_value (str): The $ref value (e.g., "#/$defs/myDef").

    Returns:
    dict: The resolved schema definition, or None if not found.
    """

    if not ref_value.startswith("#/$defs/"):
    return None # Not a defs reference

    def_path = ref_value[len("#/$defs/"):] # Extract the definition name
    if schema.get("$defs") and def_path in schema["$defs"]:
    return schema["$defs"][def_path]
    return None # Definition not found


    Example classes and code:

    import pydantic
    from typing import ClassVar, List, Optional

    from pydantic import Field, BaseModel

    class Node(BaseModel):
    myprop: str
    children: Optional["FailingNode"] = None

    class FailingNode(BaseModel):
    myprop: str
    children: Optional["FailingNode"] = None

    def resolve_ref(schema, ref_value):
    """ (as above) """
    ...

    if __name__ == "__main__":
    good = Node(myprop="good")
    goodschema = good.model_json_schema()
    print(goodschema['properties'].keys())

    bad = FailingNode(myprop="bad")
    badschema = bad.model_json_schema()

    assert 'properties' not in badschema.keys()
    resolved = resolve_ref(badschema, badschema['$ref'])
    print(resolved['properties'].keys())

    Continue reading...

Compartilhe esta Página