Skip to content

Commit e16e50e

Browse files
committed
oas30 - follow $refs in components make script runnable
1 parent 7b52bae commit e16e50e

File tree

1 file changed

+94
-10
lines changed

1 file changed

+94
-10
lines changed

ogc/bblocks/oas30.py

+94-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#!/usr/bin/env python3
22
from __future__ import annotations
33

4+
import argparse
45
import logging
6+
import os
57
import re
68
from builtins import isinstance
79
from collections import deque
@@ -10,7 +12,7 @@
1012
from urllib.parse import urlparse
1113

1214
from jsonpointer import resolve_pointer
13-
from ogc.na.util import is_url, load_yaml
15+
from ogc.na.util import is_url, load_yaml, dump_yaml
1416

1517
from ogc.bblocks.util import load_file_cached, PathOrUrl
1618

@@ -302,9 +304,15 @@ def schema_to_oas30(schema_fn: Path, schema_url: str, bbr: BuildingBlockRegister
302304
}
303305

304306

305-
def oas31_to_oas30(document: dict, document_location: PathOrUrl | str, bbr: BuildingBlockRegister | None,
307+
def oas31_to_oas30(document: dict, document_location: PathOrUrl | str, bbr: BuildingBlockRegister | None = None,
306308
x_defs_path='/x-defs', target_version='3.0.3'):
307309

310+
if not isinstance(document, dict):
311+
if isinstance(document, Path) or not is_url(document):
312+
document = load_yaml(filename=document)
313+
else:
314+
document = load_yaml(url=document)
315+
308316
# == 1. Bundle
309317
if x_defs_path[0] != '/':
310318
x_defs_path = '/' + x_defs_path
@@ -430,6 +438,12 @@ def fn(subschema: dict[str, Any], parent_is_properties=False, property=None, **k
430438
def process_path_item_object(o: dict):
431439
if not o:
432440
return
441+
442+
ref = o.get('$ref')
443+
if ref:
444+
process_path_item_object(resolve_pointer(root_schema, ref[1:]))
445+
return
446+
433447
for op_key in OAS_OPERATION_KEYS:
434448
operation = o.get(op_key)
435449
if operation:
@@ -442,25 +456,58 @@ def process_path_item_object(o: dict):
442456
def process_operation_object(o: dict):
443457
if not o:
444458
return
445-
for parameter in o.get('parameters', []):
446-
resolve_parameter(parameter)
447-
process_schema_object(parameter)
448-
process_content_object(parameter)
459+
460+
ref = o.get('$ref')
461+
if ref:
462+
process_operation_object(resolve_pointer(root_schema, ref[1:]))
463+
return
464+
465+
parameters = o.get('parameters')
466+
if isinstance(parameters, dict): # $ref!
467+
parameters = resolve_pointer(root_schema, parameters['$ref'][1:])
468+
if parameters:
469+
for parameter in parameters:
470+
resolve_parameter(parameter)
471+
process_schema_object(parameter)
472+
process_content_object(parameter)
449473

450474
process_content_object(o.get('requestBody'))
451475

452-
for response in o.get('responses', {}).values():
453-
process_content_object(response)
454-
for header in response.get('headers', {}).values():
455-
process_schema_object(header)
476+
responses = o.get('responses')
477+
if responses:
478+
ref = responses.get('$ref')
479+
if ref:
480+
responses = resolve_pointer(root_schema, ref[1:])
481+
if responses:
482+
for response in o.get('responses', {}).values():
483+
process_content_object(response)
484+
headers = response.get('headers')
485+
if headers:
486+
ref = responses.get('$ref')
487+
if ref:
488+
headers = resolve_pointer(root_schema, ref[1:])
489+
if headers:
490+
for header in headers.values():
491+
process_schema_object(header)
456492

457493
for callback in o.get('callbacks', {}).values():
458494
process_operation_object(callback)
459495

460496
def process_content_object(o: dict):
461497
if not o:
462498
return
499+
500+
ref = o.get('$ref')
501+
if ref:
502+
process_content_object(resolve_pointer(root_schema, ref[1:]))
503+
return
504+
463505
content = o.get('content')
506+
if content:
507+
ref = content.get('$ref')
508+
if ref:
509+
content = resolve_pointer(root_schema, ref[1:])
510+
464511
if content:
465512
for schema_object in content.values():
466513
# remove description because 3.0 doesn't support it
@@ -515,3 +562,40 @@ def process_document():
515562
root_schema['openapi'] = target_version
516563

517564
return root_schema
565+
566+
567+
def _main():
568+
parser = argparse.ArgumentParser(
569+
description='Downcompiles OpenApi 3.1 documents to 3.0',
570+
)
571+
572+
parser.add_argument(
573+
'document',
574+
help='Document to downcompile',
575+
)
576+
577+
parser.add_argument(
578+
'--url',
579+
help='Canonical URL of document',
580+
)
581+
582+
parser.add_argument(
583+
'-o',
584+
'--output',
585+
help='Output file'
586+
)
587+
588+
args = parser.parse_args()
589+
590+
document_location = PathOrUrl(args.url or args.document)
591+
592+
result = oas31_to_oas30(args.document, document_location)
593+
594+
if not args.output:
595+
print(dump_yaml(result))
596+
else:
597+
dump_yaml(result, args.output)
598+
599+
600+
if __name__ == '__main__':
601+
_main()

0 commit comments

Comments
 (0)