Skip to content

Commit bc23b53

Browse files
committed
Add multi-repo fallback for project_urls metadata
Artifactory might return `project_urls: null` even for public packages. Now iterates through all index_urls and falls back to PyPI.org to get VCS metadata when Artifactory has incomplete data. Signed-off-by: Kai Hodžić <hodzic.e.k@outlook.com>
1 parent ea71c68 commit bc23b53

1 file changed

Lines changed: 29 additions & 17 deletions

File tree

src/python_inspector/package_data.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,30 +52,42 @@ async def get_pypi_data_from_purl(
5252
if not version:
5353
raise Exception("Version is not specified in the purl")
5454

55-
# Todo: address the case where several index URLs are passed
56-
if index_urls:
57-
# Backward compatibility: If pypi.org is passed as index url, always resolve against it.
58-
# When multiple index URLs are supported and the todo above is fixed, then this hack can be removed.
59-
if "https://pypi.org/simple" in index_urls:
60-
index_url = None
61-
else:
62-
index_url = index_urls[0]
63-
else:
64-
index_url = None
55+
api_urls = []
56+
pypi_org_url = f"https://pypi.org/pypi/{name}/{version}/json"
57+
for index_url in index_urls or []:
58+
if index_url == "https://pypi.org/simple":
59+
continue
60+
base_path = index_url.removesuffix("/simple") + "/pypi"
61+
api_urls.append((base_path, f"{base_path}/{name}/{version}/json"))
62+
api_urls.append(("https://pypi.org/pypi", pypi_org_url))
6563

66-
base_path = (
67-
index_url.removesuffix("/simple") + "/pypi" if index_url else "https://pypi.org/pypi"
68-
)
64+
from python_inspector.utils import get_response_async
6965

70-
api_url = f"{base_path}/{name}/{version}/json"
66+
response = None
67+
api_url = None
68+
base_path = None
69+
info = {}
70+
for bp, url in api_urls:
71+
repo_response = await get_response_async(url)
72+
if not repo_response:
73+
continue
7174

72-
from python_inspector.utils import get_response_async
75+
if not response:
76+
response = repo_response
77+
api_url = url
78+
base_path = bp
79+
info = response.get("info") or {}
80+
81+
if not info.get("project_urls"):
82+
repo_info = repo_response.get("info") or {}
83+
info["project_urls"] = repo_info.get("project_urls")
84+
85+
if info.get("project_urls"):
86+
break
7387

74-
response = await get_response_async(api_url)
7588
if not response:
7689
return None
7790

78-
info = response.get("info") or {}
7991
homepage_url = info.get("home_page")
8092
project_urls = info.get("project_urls") or {}
8193
code_view_url = get_pypi_codeview_url(project_urls)

0 commit comments

Comments
 (0)