def test_traverse_object(): oas = { "components": { "parameters": { "limit": { "$ref": REPO_URL + "/parameters/parameters.yaml#/limit" }, "sort": { "$ref": REPO_URL + "/parameters/parameters.yaml#/sort" }, }, "headers": { "X-RateLimit-Limit": { "$ref": REPO_URL + "/headers/headers.yaml#/X-RateLimit-Limit" }, "Retry-After": { "$ref": REPO_URL + "/headers/headers.yaml#/Retry-After" }, }, } } resolver = OpenapiResolver(oas) ret = resolver.resolve() log.debug(resolver.dump())
def test_traverse(): oat = { "a": 1, "list_of_refs": [{"$ref": REPO_URL + "/parameters/parameters.yaml#/sort"}], "object": {"$ref": REPO_URL + "/parameters/parameters.yaml#/sort"}, } resolver = OpenapiResolver(oat) ret = resolver.resolve() assert ret == { "a": 1, "list_of_refs": [ { "name": "sort", "in": "query", "description": "Sorting order", "schema": {"type": "string", "example": "+name"}, } ], "object": { "name": "sort", "in": "query", "description": "Sorting order", "schema": {"type": "string", "example": "+name"}, }, } log.debug(resolver.dump())
def test_yaml_reference(): resolver = OpenapiResolver({}, None) ref = resolver.get_yaml_reference( "data/headers/subheaders.yaml#/headers/Retry-After" ) assert "description" in ref assert "schema" in ref
def test_resolve_relative_2(): oat = {"citizen": {"$ref": REPO_URL + "/parameters/parameters.yaml#/citizen"}} resolver = OpenapiResolver(oat) resolver.resolve() assert "schemas" in resolver.yaml_components assert "Person" in resolver.yaml_components["schemas"] log.debug(resolver.dump())
def test_resolve_local(): with open("testcase.yaml") as fh: oat = yaml.safe_load(fh.read()) resolver = OpenapiResolver(oat["test_resolve_local"]) resolver.resolve() out = yaml.safe_load(resolver.dump()) assert "Problem" in out["components"]["schemas"]
def test_validate_resolved(): simple_yaml = "tests/simple.yaml" oas = yaml_load_file(simple_yaml, cb=replace_branch_name) resolver = OpenapiResolver(oas) oas_resolved = resolver.dump_yaml() validate_spec(oas_resolved) Path("tests/out.simple.yaml").write_text(resolver.dump())
def test_resolve_subreference_fix7_1(): fpath = Path("data/subreference.yaml") oat = yaml_load_file(str(fpath)) resolver = OpenapiResolver(oat, str(fpath.resolve())) resolver.resolve() yaml_ = resolver.dump_yaml() components = defaultdict(dict, yaml_.pop("components")) log.debug(yaml_dump(components)) assert components["schemas"]["TaxCode"]
def test_nested_reference(): oat = { "400BadRequest": {"$ref": REPO_URL + "/responses/responses.yaml#/400BadRequest"} } resolver = OpenapiResolver(oat) resolver.resolve() assert "schemas" in resolver.yaml_components assert "Problem" in resolver.yaml_components["schemas"] log.debug(resolver.dump())
def assemble(): #repo = git.Repo(".") #commit = repo.head.commit definitions = {} doc_dir = Path("docs") for f in doc_dir.rglob("*.yaml"): if f.name in SKIP_FILES: continue component = f.parent.name if component not in definitions: definitions[component] = {} definitions[component].update(get_yaml(f)) write_yaml(definitions, "tests/tmp.bundle.yaml") r = OpenapiResolver(definitions, str(f)) resolved = r.resolve() write_yaml(resolved, "tmp.bundle.resolverd.yaml") # Prepare metadata output. info = get_yaml(Path("info.yaml")) if "info" not in info: raise ValueError("Error: info.yaml does not contain 'info' section.") # if not repo.head.is_detached: # version = repo.active_branch.name # else: # version_tag = next( # (tag for tag in repo.tags if tag.commit == repo.head.commit), None # ) # if not version_tag: # raise NotImplementedError( # "The current state should be an active_branch or a tag." # ) # version = version_tag.name # # info["info"].update( # { # "commit": str(commit), # "date": commit.committed_date, # "version": version, # } # ) # committed_datetime = datetime.fromtimestamp( # commit.committed_date # ).isoformat() p = Path("docs/definitions.yaml") with p.open("w") as fh: # fh.write(f"# {committed_datetime}\n") fh.write(OpenapiResolver.yaml_dump_pretty(info)) fh.write( OpenapiResolver.yaml_dump_pretty(resolved).replace( "#/components/", "#/"))
def test_resolve_subreference_fix6_2(): fpath = Path("data/subreference.yaml") oat = yaml_load_file(str(fpath)) resolver = OpenapiResolver(oat, str(fpath.resolve())) resolver.resolve() yaml_ = resolver.dump_yaml() components = defaultdict(dict, yaml_.pop("components")) log.debug(yaml_dump(components)) assert components["responses"]["429TooManyRequests"] assert components["schemas"]["Problem"] assert components["headers"]["Retry-After"]
def test_resolve_subreference_fix6(): # preserve nested objects. fpath = Path("data/headers/subheaders.yaml") oat = yaml_load_file(str(fpath)) resolver = OpenapiResolver(oat, str(fpath)) resolver.resolve() yaml_ = resolver.dump_yaml() components = defaultdict(dict, yaml_.pop("components")) components[fpath.parent.name].update(yaml_) log.debug(yaml_dump(components)) assert components["headers"]["headers"]
def test_resolve_relative(): oat = { "429TooManyRequests": { "$ref": REPO_URL + "/responses/responses.yaml#/429TooManyRequests" } } resolver = OpenapiResolver(oat) resolver.resolve() assert "schemas" in resolver.yaml_components assert "Problem" in resolver.yaml_components["schemas"] assert "headers" in resolver.yaml_components assert "Retry-After" in resolver.yaml_components["headers"] log.debug(resolver.dump())
def test_resolve_subreference_fix6_1(): oat = { "components": { "headers": { "X-Foo": {"$ref": "data/headers/subheaders.yaml#/headers/Retry-After"} } } } resolver = OpenapiResolver(oat, None) resolver.resolve() yaml_ = resolver.dump_yaml() components = defaultdict(dict, yaml_.pop("components")) log.debug(yaml_dump(components)) assert components["headers"]["Retry-After"]
def test_resolve_local_2(): # load files from different paths # and resolve relative references. fpath = Path("data/responses/responses.yaml") oat = yaml_load_file(str(fpath)) resolver = OpenapiResolver(oat, str(fpath)) resolver.resolve() yaml_ = resolver.dump_yaml() components = defaultdict(dict, yaml_.pop("components")) components[fpath.parent.name].update(yaml_) log.debug(yaml_dump(components)) assert components["headers"]["Retry-After"] assert components["schemas"]["Problem"]
def test_resolve_local_3(): # load files from different paths # and resolve relative references. fpath = Path("data/parameters/parameters.yaml") oat = yaml_load_file(str(fpath)) resolver = OpenapiResolver(oat, str(fpath)) resolver.resolve() yaml_ = resolver.dump_yaml() components = defaultdict(dict, yaml_.pop("components")) components[fpath.parent.name].update(yaml_) log.debug(yaml_dump(components)) assert components["schemas"]["Person"] assert components["parameters"]["citizen"]["schema"] assert components["schemas"]["TaxCode"]
def show_component(url): U = urlparse(url) fragment = U.fragment.strip('/').split('/') ret = yaml.safe_load(get(url).content) for k in fragment: ret = ret[k] return OpenapiResolver.yaml_dump_pretty(ret)
def __init__(self, ui, schema, font_size=11, font_size_form=None, data=DATA): """ :param ui: object containing ui-schema :param schema: structure containing the schema """ self.ui = ui # Use jsonref.loads to resolve $ref in schema. If we want to use external # references we need external resolver. schema_resolve_external = OpenapiResolver(schema).resolve() self.schema = jsonref.loads(json.dumps(schema_resolve_external)) self.resolver = jsonschema.RefResolver.from_schema(self.schema) self.font_size = font_size self.font_size_form = font_size_form or font_size self.data = data or {} self.line_feed = 5 * self.font_size self.root = ET.Element("html") head = ET.SubElement(self.root, "head") style = ET.SubElement(head, "link", { "href": "form.css", "rel": "stylesheet" }) self.body = ET.SubElement(self.root, "body") self.form = ET.SubElement(self.body, "form", attrib={ "action": "", "method": "post" })
def parseAPI(api_dir: str = "./datanator_rest_api/spec/", src_file: str = "root.yaml"): """ Takes the root open api yaml file and resolves the embedded refrences for local and remote yaml files. Generates a complete JSON specification of the API Args: api_dir (str): The directory storing the api definition src_file (str): The name of the root api file Returns: str : A string containing the parsed API """ abspath = os.path.abspath(__file__) dname = os.path.dirname(abspath) os.chdir(dname) with open(src_file) as api_src: ret = yaml.safe_load(api_src) resolver = OpenapiResolver(ret) resolver.resolve() res = resolver.dump() return res
def bundle_file(schema=None, fpath=None): if not (schema or fpath): raise ValueError("Pass at least one of schema and fpath") yaml_data = schema or yaml.safe_load(Path(fpath).read_text()) if fpath: chdir(dirname(fpath)) try: yaml_resolved = OpenapiResolver(yaml_data).resolve() finally: if fpath: chdir("..") return yaml_resolved
def test_resolve_file(): oat = yaml.safe_load(Path("tests/data/simple.yaml").read_text()) resolver = OpenapiResolver(oat) resolver.resolve() out = yaml.safe_load(resolver.dump()) Path("data/simple.out.yaml").write_text(resolver.dump()) assert "Problem" in out["components"]["schemas"]
def test_dump(): oat = { "openapi": "3.0.1", "x-commons": {}, "components": { "responses": { "400BadRequest": { "$ref": REPO_URL + "/responses/responses.yaml#/400BadRequest" } } }, } resolver = OpenapiResolver(oat) resolver.resolve() assert "400BadRequest:" in resolver.dump() assert "x-commons" not in resolver.dump()
def test_dump_noanchor(): oat = { "/organization_list": { "get": { "description": "List or search all datasets\n", "operationId": "listOrgs", "responses": { "200": {"$ref": "#/components/responses/CkanResponse"}, "400": {"$ref": "#/components/responses/400BadRequest"}, "429": {"$ref": "#/components/responses/429TooManyRequests"}, "503": {"$ref": "#/components/responses/503ServiceUnavailable"}, "default": {"$ref": "#/components/responses/default"}, }, "summary": "List all groups within given parameters", "tags": ["public"], } }, "/package_list": { "get": { "description": "List or search all datasets\n", "operationId": "listInventory", "responses": { "200": {"$ref": "#/components/responses/CkanResponse"}, "400": {"$ref": "#/components/responses/400BadRequest"}, "429": {"$ref": "#/components/responses/429TooManyRequests"}, "503": {"$ref": "#/components/responses/503ServiceUnavailable"}, "default": {"$ref": "#/components/responses/default"}, }, "summary": "List all datasets within given limit", "tags": ["public"], } }, "/package_search": { "get": { "description": "List or search all datasets\n", "operationId": "searchInventory", "responses": { "200": {"$ref": "#/components/responses/CkanResponse"}, "400": {"$ref": "#/components/responses/400BadRequest"}, "409": { "description": "Conflict (can result e.g. from incorrectly formatted solr query)" }, "429": {"$ref": "#/components/responses/429TooManyRequests"}, "503": {"$ref": "#/components/responses/503ServiceUnavailable"}, "default": {"$ref": "#/components/responses/default"}, }, "summary": "Search among all datasets", "tags": ["public"], } }, "/package_show": { "get": { "description": "List or search all datasets\n", "operationId": "showInventory", "responses": { "200": {"$ref": "#/components/responses/CkanResponse"}, "400": {"$ref": "#/components/responses/400BadRequest"}, "429": {"$ref": "#/components/responses/429TooManyRequests"}, "503": {"$ref": "#/components/responses/503ServiceUnavailable"}, "default": {"$ref": "#/components/responses/default"}, }, "summary": "Get details of one package", "tags": ["public"], } }, "/user_list": { "get": { "description": "List or search all datasets\n", "operationId": "listUsers", "responses": { 200: {"$ref": "#/components/responses/CkanResponse"}, "400": {"$ref": "#/components/responses/400BadRequest"}, "429": {"$ref": "#/components/responses/429TooManyRequests"}, "503": {"$ref": "#/components/responses/503ServiceUnavailable"}, "default": {"$ref": "#/components/responses/default"}, }, "summary": "List all groups within given parameters", "tags": ["consumers"], } }, } resolver = OpenapiResolver(oat) resolver.resolve() log.debug(resolver.dump()) assert "*id" not in resolver.dump()
def write_yaml(src, dst): p = Path(dst) p.write_text(OpenapiResolver.yaml_dump_pretty(src))