datamodel-code-generator icon indicating copy to clipboard operation
datamodel-code-generator copied to clipboard

Error parsing external relative ref that contains a local ref

Open kepler opened this issue 3 years ago • 0 comments

Describe the bug Parsing fails with a KeyError when processing an external ref that contains a local ref.

/datamodel_code_generator/parser/jsonschema.py", line 54, in get_model_by_path
    return get_model_by_path(schema[keys[0]], keys[1:])
KeyError: 'model_a'

To Reproduce

With two schemas in separate paths, which are to be processed separately but can reference each other: File model_a/types.openapi.yaml:


 ---
openapi: 3.0.3
info:
  title: Model A definitions
  version: "1.0"

paths: {}


components:
  schemas:

    model_a.input:
      type: object
      properties:
        name:
          type: string

    model_a.output:
      type: object
      properties:
        output:
          type: string
        input:
          $ref: "#/components/schemas/model_a.input"

Running the following works as expected:

$ datamodel-codegen --input model_a --output tmp/

Now consider a second file, model_b/module.openapi.yaml, that references model_a.input:


---
openapi: 3.0.3
info:
  title: Model B definitions
  version: "1.0"

paths: {}


components:
  schemas:
    modules.quality_evaluation.QualityEvaluationRequest:
      type: object
      properties:
        input:
          $ref: "../model_a/types.openapi.yaml#/components/schemas/model_a.input"

Running the following also works as expected:

$ datamodel-codegen --input model_b --output tmp/

But now, if instead we ref to model_a.output, which contains a ref itself:


---
openapi: 3.0.3
info:
  title: Model B definitions
  version: "1.0"

paths: {}


components:
  schemas:
    modules.quality_evaluation.QualityEvaluationRequest:
      type: object
      properties:
        input:
          $ref: "../model_a/types.openapi.yaml#/components/schemas/model_a.output"

Then running:

$ datamodel-codegen --input model_b --output tmp/

breaks the following:

Traceback (most recent call last):
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/__main__.py", line 495, in main
    generate(
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/__init__.py", line 353, in generate
    results = parser.parse()
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/parser/base.py", line 426, in parse
    self.parse_raw()
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/parser/openapi.py", line 385, in parse_raw
    self.parse_raw_obj(
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/parser/jsonschema.py", line 1122, in parse_raw_obj
    self.parse_obj(name, JsonSchemaObject.parse_obj(raw), path)
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/parser/jsonschema.py", line 1142, in parse_obj
    self.parse_ref(obj, path)
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/parser/jsonschema.py", line 1084, in parse_ref
    self.parse_ref(value, path)
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/parser/jsonschema.py", line 1064, in parse_ref
    self.resolve_ref(obj.ref)
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/parser/jsonschema.py", line 1053, in resolve_ref
    self._parse_file(
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/parser/jsonschema.py", line 1266, in _parse_file
    models = get_model_by_path(raw, object_paths)
  File "/VENV/lib/python3.9/site-packages/datamodel_code_generator/parser/jsonschema.py", line 54, in get_model_by_path
    return get_model_by_path(schema[keys[0]], keys[1:])
KeyError: 'model_a'

Expected behavior The local ref of the external ref is successfully parsed.

Version:

  • OS: Ubuntu 20.10
  • Python version: 3.9.8
  • datamodel-code-generator version: 0.11.15

Additional context Please let me know if this is expected behavior (not to fully parse the whole schema file of external references).

kepler avatar Feb 15 '22 10:02 kepler