Skip to content

Commit 1296b3f

Browse files
committed
feat: use pypi api directly to get urls
1 parent ebcf0a3 commit 1296b3f

File tree

5 files changed

+78
-4
lines changed

5 files changed

+78
-4
lines changed

conda_forge_tick/update_recipe/version.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import jinja2
1515
import jinja2.sandbox
16+
import requests
1617
from conda_forge_feedstock_ops.container_utils import (
1718
get_default_log_level_args,
1819
run_container_operation,
@@ -140,6 +141,72 @@ def _render_jinja2(tmpl, context):
140141
)
141142

142143

144+
def _try_pypi_api(url_tmpl: str, context: MutableMapping, hash_type: str):
145+
if "name" not in context:
146+
return None, None
147+
148+
if "version" not in context:
149+
return None, None
150+
151+
if not any(pypi_slug in url_tmpl for pypi_slug in ["/pypi.org", "/pypi.io", "/files.pythonhosted.org"]):
152+
return None, None
153+
154+
r = requests.get(
155+
f"https://pypi.org/simple/{context['name']}/",
156+
headers={"Accept": "application/vnd.pypi.simple.v1+json"}
157+
)
158+
r.raise_for_status()
159+
160+
data = r.json()
161+
logger.debug("PyPI API data:\n%s", pprint.pformat(data))
162+
163+
valid_src_exts = {".tar.gz", ".tar.bz2", ".tar.xz", ".zip", ".tgz"}
164+
finfo = None
165+
ext = None
166+
for _finfo in data["files"]:
167+
for valid_ext in valid_src_exts:
168+
if _finfo["filename"].endswith(context["version"] + valid_ext):
169+
ext = valid_ext
170+
finfo = _finfo
171+
break
172+
173+
if finfo is None or ext is None:
174+
logger.debug("src dist for version %s not found in PyPI API", context["version"])
175+
return None, None
176+
177+
bn, _ = os.path.split(url_tmpl)
178+
pypi_name = finfo["filename"].split(context["version"] + ext)[0]
179+
logger.debug("PyPI API file name: %s", pypi_name)
180+
name_tmpl = None
181+
for tmpl in [
182+
"{{ name }}",
183+
"{{ name.lower() }}",
184+
"{{ name.replace('-', '_') }}",
185+
"{{ name.replace('_', '-') }}",
186+
"{{ name.replace('-', '_').lower() }}",
187+
"{{ name.replace('_', '-').lower() }}",
188+
]:
189+
if pypi_name == _render_jinja2(tmpl, context) + "-":
190+
name_tmpl = tmpl
191+
break
192+
193+
if name_tmpl is not None:
194+
new_url_tmpl = os.path.join(bn, name_tmpl + "-" + "{{ version }}" + ext)
195+
else:
196+
new_url_tmpl = os.path.join(bn, finfo["filename"].replace(context["version"], "{{ version }}"))
197+
198+
logger.debug("new url template from PyPI API: %s", new_url_tmpl)
199+
url = _render_jinja2(new_url_tmpl, context)
200+
new_hash = _try_url_and_hash_it(url, hash_type)
201+
if new_hash is not None:
202+
return new_url_tmpl, new_hash
203+
204+
new_url_tmpl = finfo["url"]
205+
new_hash = _try_url_and_hash_it(url, hash_type)
206+
if new_hash is not None:
207+
return new_url_tmpl, new_hash
208+
209+
143210
def _get_new_url_tmpl_and_hash(url_tmpl: str, context: MutableMapping, hash_type: str):
144211
logger.info(
145212
"hashing URL template: %s",
@@ -165,6 +232,13 @@ def _get_new_url_tmpl_and_hash(url_tmpl: str, context: MutableMapping, hash_type
165232
new_url_tmpl = None
166233
new_hash = None
167234

235+
try:
236+
new_url_tmpl, new_hash = _try_pypi_api(url_tmpl, context, hash_type)
237+
if new_hash is not None and new_url_tmpl is not None:
238+
return new_url_tmpl, new_hash
239+
except Exception as e:
240+
logger.debug("PyPI API url+hash update failed: %s", repr(e), exc_info=e)
241+
168242
for new_url_tmpl in gen_transformed_urls(url_tmpl):
169243
try:
170244
url = _render_jinja2(new_url_tmpl, context)

tests/test_yaml/version_21cmfast_correct.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package:
66
version: {{ version }}
77

88
source:
9-
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name|lower }}/{{ name|lower }}-{{ version }}.tar.gz
9+
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name.lower() }}-{{ version }}.tar.gz
1010
sha256: aff3b5a2adb30ad9a6c2274461901686606e9fdb5e3ff7040cbdf22755d7469f
1111

1212

tests/test_yaml/version_dash_extensions_correct.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ package:
77
version: {{ version }}
88

99
source:
10-
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name.replace('-', '_').lower() }}/{{ name.replace('-', '_').lower() }}-{{ version }}.tar.gz
10+
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name.replace('-', '_') }}-{{ version }}.tar.gz
1111
sha256: b36fcf6fd74d87cafdbabc9568c3ae0097712ccee8f7d59be8e916b51d40b106
1212

1313
build:

tests/test_yaml/version_pypiurl_correct.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package:
66
version: "{{ version }}"
77

88
source:
9-
url: "https://pypi.io/packages/source/{{ name[0] }}/{{ name.replace('_', '-').lower() }}/{{ name.replace('_', '-').lower() }}-{{ version }}.tar.gz"
9+
url: "https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name.replace('_', '-') }}-{{ version }}.tar.gz"
1010
sha256: f3fe3f89011899b82451669cf1dbe4978523b8ac0f62c9c116429876fe8b6be8
1111

1212
build:

tests/test_yaml/version_pyrsmq_correct.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package:
66
version: "{{ version }}"
77

88
source:
9-
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name|lower }}-{{ version }}.tar.gz
9+
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name.lower() }}-{{ version }}.tar.gz
1010
sha256: dd1f8467e541935489be018dbb0ba1df8b903eb855bf1725947ceee41df92fa4
1111

1212
build:

0 commit comments

Comments
 (0)