Skip to content
Open
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e983f04
parser / properties / resolve local $ref
Nementon Feb 7, 2021
49c1ed1
parser/ propertoes / add `LazyReferencePropertyProxy`: lazy resolve r…
Nementon Feb 19, 2021
b27a003
test / parser / properties / correct references arranged data, use lo…
Nementon Feb 20, 2021
32698b0
test / parser / properties / add `LazyReferencePropertyProxy` tests
Nementon Feb 20, 2021
f7940b6
parser / properties / tiny code clean up
Nementon Feb 20, 2021
7b373d2
parser / properties / use lazy reference only for reference to themself
Nementon Feb 21, 2021
ebb8e62
test / parser / properties / correct `LazyReferencePropertyProxy` tests
Nementon Feb 21, 2021
0f445ac
parser / propertie / add support for indirect reference to itself res…
Nementon Feb 21, 2021
1970fd6
parser / properties / rename `_reference_name` -> `_reference_pointer…
Nementon Feb 21, 2021
ce6bb1e
test / parser / properties / correct API breaking changes
Nementon Feb 21, 2021
d3d7bbe
parser / properties / tests cleanup + behaviour fixes
Nementon Feb 21, 2021
1de3190
parser / properties / LazyReferencePropertyProxy: quote resolved type…
Nementon Feb 21, 2021
c7a1371
parser / properties / LazyReferencePropertyProxy: enforce nullable to…
Nementon Feb 21, 2021
8334c03
golden records / regen / add indirect, self, indirect-self model refe…
Nementon Feb 21, 2021
d0a2e6e
update CHANGELOG
Nementon Feb 21, 2021
1e996d2
bootstrap schemas resolver
Nementon Feb 5, 2021
b183460
__init__ / _get_document: use SchemaResolver
Nementon Feb 5, 2021
cedb946
resolver / wip resolve remote ref to local ones
Nementon Feb 6, 2021
e38a6ad
correct tests breaking changes
Nementon Feb 10, 2021
b60c382
resolver / refactor (squash me)
Nementon Feb 11, 2021
229f75f
resolver / add reference tests
Nementon Feb 11, 2021
325a8a7
resolver / add data_loader tests
Nementon Feb 11, 2021
582115c
resolver / add schema_resolver tests (wip)
Nementon Feb 11, 2021
91eb471
resovler / add pointer tests
Nementon Feb 12, 2021
08beec5
resolver / refactor (squash me)
Nementon Feb 14, 2021
97a2e56
resolver / add schema_resolver tests (squash me)
Nementon Feb 14, 2021
ca2dc41
fix absolute paths feature bugs
p1-alexandrevaney Mar 8, 2021
250fa6a
add collision_resolver
p1-alexandrevaney Mar 12, 2021
bb61e8a
fix collision issues with same schema in two different filesé
p1-alexandrevaney Mar 15, 2021
5fafa0a
do not crash on retry of key modification
p1-alexandrevaney Mar 15, 2021
8383bb3
find collision of 2 same object at different place
p1-alexandrevaney Mar 15, 2021
692bd1a
use tokens instead of splitting paths
p1-alexandrevaney Mar 15, 2021
aa04afe
remove ref key when replacing it
p1-alexandrevaney Mar 16, 2021
6b584b6
fix build_schema bug when model points to loaded ref
p1-alexandrevaney Mar 18, 2021
0ce86cd
add json loading to data_loader
p1-alexandrevaney Mar 18, 2021
2b3c125
dont use resolved schema in collision resolver
p1-alexandrevaney Mar 18, 2021
aae98e7
improve collision resolver and resolved schema tests
p1-alexandrevaney Mar 19, 2021
a624a88
fix data_load json test
p1-alexandrevaney Mar 19, 2021
59fb49b
add new tests for coverage purposes
p1-alexandrevaney Mar 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
resolver / refactor (squash me)
  • Loading branch information
Nementon authored and p1-alexandrevaney committed Mar 15, 2021
commit 08beec544fee4fb0905e6d21f1dc4137159587c6
75 changes: 53 additions & 22 deletions openapi_python_client/resolver/schema_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ def __init__(self, url_or_path: Union[str, Path]):
raise ValueError("Invalid document root reference, it shall be an remote url or local file path")

self._root_path: Union[Path, None] = None
self._root_path_dir: Union[Path, None] = None
self._root_url: Union[str, None] = None
self._root_url_scheme: Union[str, None] = None
self._parent_path: str

if self._isapath(url_or_path):
url_or_path = cast(Path, url_or_path)
self._root_path = url_or_path.absolute()
self._root_path_dir = self._root_path.parent
self._parent_path = str(self._root_path.parent)
else:
url_or_path = cast(str, url_or_path)
self._root_url = url_or_path
self._parent_path = url_or_path
try:
self._root_url_scheme = urllib.parse.urlparse(url_or_path).scheme
if self._root_url_scheme not in ["http", "https"]:
Expand All @@ -44,59 +45,89 @@ def resolve(self, recursive: bool = True) -> ResolvedSchema:
root_schema: SchemaData
external_schemas: Dict[str, SchemaData] = {}
errors: List[str] = []
parent: str

if self._root_path:
root_schema = self._fetch_remote_file_path(self._root_path)
elif self._root_url:
root_schema = self._fetch_url_reference(self._root_url)

self._resolve_schema_references(root_schema, external_schemas, errors, recursive)
self._resolve_schema_references(self._parent_path, root_schema, external_schemas, errors, recursive)
return ResolvedSchema(root_schema, external_schemas, errors)

def _resolve_schema_references(
self, root: SchemaData, external_schemas: Dict[str, SchemaData], errors: List[str], recursive: bool
self,
parent: str,
root: SchemaData,
external_schemas: Dict[str, SchemaData],
errors: List[str],
recursive: bool,
) -> None:

for ref in self._lookup_schema_references(root):
if ref.is_local():
continue

try:
path = ref.value.split("#")[0]
path = self._absolute_path(ref.path, parent)
parent = self._parent(path)

if path in external_schemas:
continue

if ref.is_url():
external_schemas[path] = self._fetch_url_reference(path)
else:
external_schemas[path] = self._fetch_remote_reference(path)
external_schemas[path] = self._fetch_remote_reference(path)

if recursive:
self._resolve_schema_references(external_schemas[path], external_schemas, errors, recursive)
self._resolve_schema_references(parent, external_schemas[path], external_schemas, errors, recursive)

except Exception:
errors.append("Failed to gather external reference data of {0}".format(ref.value))
logging.exception("Failed to gather external reference data of {0}".format(ref.value))
errors.append(f"Failed to gather external reference data of {ref.value} from {path}")
logging.exception(f"Failed to gather external reference data of {ref.value} from {path}")

def _fetch_remote_reference(self, relative_path: str) -> SchemaData:
assert self._root_path_dir or self._root_url
def _parent(self, abs_path: str) -> str:
if abs_path.startswith("http", 0):
return urllib.parse.urljoin(f"{abs_path}/", "..")
else:
path = Path(abs_path)
return str(path.parent)

def _absolute_path(self, relative_path: str, parent: str) -> str:
if relative_path.startswith("http", 0):
return relative_path

if relative_path.startswith("//"):
if parent.startswith("http"):
scheme = urllib.parse.urlparse(parent).scheme
return f"{scheme}:{relative_path}"
else:
scheme = self._root_url_scheme or "http"
return f"{scheme}:{relative_path}"

if parent.startswith("http"):
return urllib.parse.urljoin(parent, relative_path)
else:
parent_dir = Path(parent)
abs_path = parent_dir.joinpath(relative_path)
abs_path = abs_path.resolve()
return str(abs_path)

if self._root_path_dir:
abs_path = self._root_path_dir.joinpath(relative_path)
return self._fetch_remote_file_path(abs_path)
elif self._root_url:
abs_url = urllib.parse.urljoin(self._root_url, relative_path)
return self._fetch_url_reference(abs_url)
def _fetch_remote_reference(self, abs_path: str) -> SchemaData:
res: SchemaData

if abs_path.startswith("http"):
res = self._fetch_url_reference(abs_path)
else:
raise RuntimeError("Bad object initilalization")
res = self._fetch_remote_file_path(Path(abs_path))

return res

def _fetch_remote_file_path(self, path: Path) -> SchemaData:
logging.info(f"Fetching remote ref file path > {path}")
return DataLoader.load(str(path), path.read_bytes())

def _fetch_url_reference(self, url: str) -> SchemaData:
if url.startswith("//", 0):
url = "{0}:{1}".format(self._root_url_scheme, url)
url = "{0}:{1}".format((self._root_url_scheme or "http"), url)

logging.info(f"Fetching remote ref url > {url}")
return DataLoader.load(url, httpx.get(url).content)
Expand Down