Skip to content

Commit f1469e8

Browse files
authored
Merge pull request #3159 from regro/pypi-api
feat: use pypi api directly to get urls
2 parents ebcf0a3 + 1257ed9 commit f1469e8

8 files changed

+176
-4
lines changed

conda_forge_tick/update_recipe/version.py

Lines changed: 81 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,79 @@ 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(
152+
pypi_slug in url_tmpl
153+
for pypi_slug in ["/pypi.org", "/pypi.io", "/files.pythonhosted.org"]
154+
):
155+
return None, None
156+
157+
r = requests.get(
158+
f"https://pypi.org/simple/{context['name']}/",
159+
headers={"Accept": "application/vnd.pypi.simple.v1+json"},
160+
)
161+
r.raise_for_status()
162+
163+
data = r.json()
164+
logger.debug("PyPI API data:\n%s", pprint.pformat(data))
165+
166+
valid_src_exts = {".tar.gz", ".tar.bz2", ".tar.xz", ".zip", ".tgz"}
167+
finfo = None
168+
ext = None
169+
for _finfo in data["files"]:
170+
for valid_ext in valid_src_exts:
171+
if _finfo["filename"].endswith(context["version"] + valid_ext):
172+
ext = valid_ext
173+
finfo = _finfo
174+
break
175+
176+
if finfo is None or ext is None:
177+
logger.debug(
178+
"src dist for version %s not found in PyPI API", context["version"]
179+
)
180+
return None, None
181+
182+
bn, _ = os.path.split(url_tmpl)
183+
pypi_name = finfo["filename"].split(context["version"] + ext)[0]
184+
logger.debug("PyPI API file name: %s", pypi_name)
185+
name_tmpl = None
186+
for tmpl in [
187+
"{{ name }}",
188+
"{{ name.lower() }}",
189+
"{{ name.replace('-', '_') }}",
190+
"{{ name.replace('_', '-') }}",
191+
"{{ name.replace('-', '_').lower() }}",
192+
"{{ name.replace('_', '-').lower() }}",
193+
]:
194+
if pypi_name == _render_jinja2(tmpl, context) + "-":
195+
name_tmpl = tmpl
196+
break
197+
198+
if name_tmpl is not None:
199+
new_url_tmpl = os.path.join(bn, name_tmpl + "-" + "{{ version }}" + ext)
200+
else:
201+
new_url_tmpl = os.path.join(
202+
bn, finfo["filename"].replace(context["version"], "{{ version }}")
203+
)
204+
205+
logger.debug("new url template from PyPI API: %s", new_url_tmpl)
206+
url = _render_jinja2(new_url_tmpl, context)
207+
new_hash = _try_url_and_hash_it(url, hash_type)
208+
if new_hash is not None:
209+
return new_url_tmpl, new_hash
210+
211+
new_url_tmpl = finfo["url"]
212+
new_hash = _try_url_and_hash_it(url, hash_type)
213+
if new_hash is not None:
214+
return new_url_tmpl, new_hash
215+
216+
143217
def _get_new_url_tmpl_and_hash(url_tmpl: str, context: MutableMapping, hash_type: str):
144218
logger.info(
145219
"hashing URL template: %s",
@@ -165,6 +239,13 @@ def _get_new_url_tmpl_and_hash(url_tmpl: str, context: MutableMapping, hash_type
165239
new_url_tmpl = None
166240
new_hash = None
167241

242+
try:
243+
new_url_tmpl, new_hash = _try_pypi_api(url_tmpl, context, hash_type)
244+
if new_hash is not None and new_url_tmpl is not None:
245+
return new_url_tmpl, new_hash
246+
except Exception as e:
247+
logger.debug("PyPI API url+hash update failed: %s", repr(e), exc_info=e)
248+
168249
for new_url_tmpl in gen_transformed_urls(url_tmpl):
169250
try:
170251
url = _render_jinja2(new_url_tmpl, context)

tests/test_version_migrator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
("quart_trio", "0.11.1"),
6262
("reproc", "14.2.5"),
6363
("riskfolio_lib", "6.3.1"),
64+
("algotree", "0.7.3"),
6465
# these contain sources that depend on conda build config variants
6566
pytest.param(
6667
"polars_mixed_selectors",

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{% set name = "algotree" %}
2+
{% set version = "0.7.2" %}
3+
4+
package:
5+
name: {{ name|lower }}
6+
version: {{ version }}
7+
8+
source:
9+
url: https://pypi.org/packages/source/{{ name[0] }}/{{ name }}/algotree-{{ version }}.tar.gz
10+
sha256: 13bb4dc6583a58e1784adee20f4d803bd4105359f1c6f52151e496d23f07152a
11+
12+
build:
13+
entry_points:
14+
- jt=bin.jt:main
15+
noarch: python
16+
script: {{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation
17+
number: 0
18+
19+
requirements:
20+
host:
21+
- python >=3.6
22+
- pip
23+
- setuptools
24+
run:
25+
- python >=3.6
26+
27+
test:
28+
imports:
29+
- AlgoTree
30+
commands:
31+
- pip check
32+
- jt --help
33+
requires:
34+
- pip
35+
36+
about:
37+
home: https://github.com/queelius/AlgoTree
38+
doc_url: https://queelius.github.io/AlgoTree/
39+
summary: A algorithmic tookit for working with trees in Python
40+
license: MIT
41+
license_file: LICENSE
42+
43+
extra:
44+
recipe-maintainers:
45+
- thewchan
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{% set name = "algotree" %}
2+
{% set version = "0.7.3" %}
3+
4+
package:
5+
name: {{ name|lower }}
6+
version: {{ version }}
7+
8+
source:
9+
url: https://pypi.org/packages/source/{{ name[0] }}/{{ name }}/AlgoTree-{{ version }}.tar.gz
10+
sha256: 349eee21a57c5f40f157be218788f944a723047b35b7945a56058219b383287d
11+
12+
build:
13+
entry_points:
14+
- jt=bin.jt:main
15+
noarch: python
16+
script: {{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation
17+
number: 0
18+
19+
requirements:
20+
host:
21+
- python >=3.6
22+
- pip
23+
- setuptools
24+
run:
25+
- python >=3.6
26+
27+
test:
28+
imports:
29+
- AlgoTree
30+
commands:
31+
- pip check
32+
- jt --help
33+
requires:
34+
- pip
35+
36+
about:
37+
home: https://github.com/queelius/AlgoTree
38+
doc_url: https://queelius.github.io/AlgoTree/
39+
summary: A algorithmic tookit for working with trees in Python
40+
license: MIT
41+
license_file: LICENSE
42+
43+
extra:
44+
recipe-maintainers:
45+
- thewchan

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)