Skip to content

Commit d81c9e4

Browse files
committed
tmp
1 parent 376106b commit d81c9e4

File tree

2 files changed

+69
-20
lines changed

2 files changed

+69
-20
lines changed

pulp_python/app/utils.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import hashlib
12
import pkginfo
23
import re
34
import shutil
45
import tempfile
6+
import zipfile
57
import json
68
from collections import defaultdict
79
from django.conf import settings
@@ -130,7 +132,7 @@ def parse_project_metadata(project):
130132
# Release metadata
131133
"packagetype": project.get("packagetype") or "",
132134
"python_version": project.get("python_version") or "",
133-
"metadata_sha256": "", # TODO
135+
"metadata_sha256": project.get("metadata_sha256") or "",
134136
}
135137

136138

@@ -158,9 +160,9 @@ def parse_metadata(project, version, distribution):
158160
package["url"] = distribution.get("url") or ""
159161
package["sha256"] = distribution.get("digests", {}).get("sha256") or ""
160162
package["python_version"] = distribution.get("python_version") or package.get("python_version")
161-
package["requires_python"] = distribution.get("requires_python") or package.get(
162-
"requires_python"
163-
) # noqa: E501
163+
package["requires_python"] = distribution.get("requires_python") or "" # package.get(
164+
# "requires_python"
165+
# ) # noqa: E501
164166
package["metadata_sha256"] = distribution.get("data-dist-info-metadata", {}).get(
165167
"sha256"
166168
) or package.get("metadata_sha256")
@@ -181,6 +183,7 @@ def get_project_metadata_from_file(filename):
181183
packagetype = DIST_EXTENSIONS[extensions[pkg_type_index]]
182184

183185
metadata = DIST_TYPES[packagetype](filename)
186+
metadata.metadata_sha256 = compute_metadata_sha256(filename)
184187
metadata.packagetype = packagetype
185188
if packagetype == "sdist":
186189
metadata.python_version = "source"
@@ -193,6 +196,23 @@ def get_project_metadata_from_file(filename):
193196
return metadata
194197

195198

199+
def compute_metadata_sha256(filename: str) -> str:
200+
"""
201+
Compute SHA256 hash of the metadata file from a Python package.
202+
203+
Returns SHA256 hash or empty string if metadata cannot be extracted.
204+
"""
205+
if not filename.endswith(".whl"):
206+
return ""
207+
208+
with zipfile.ZipFile(filename, "r") as f:
209+
for file_path in f.namelist():
210+
if file_path.endswith(".dist-info/METADATA"):
211+
metadata_content = f.read(file_path)
212+
return hashlib.sha256(metadata_content).hexdigest()
213+
return ""
214+
215+
196216
def artifact_to_python_content_data(filename, artifact, domain=None):
197217
"""
198218
Takes the artifact/filename and returns the metadata needed to create a PythonPackageContent.
@@ -448,7 +468,7 @@ def write_simple_detail_json(project_name, project_packages):
448468
"filename": package["filename"],
449469
"url": package["url"],
450470
"hashes": {"sha256": package["sha256"]},
451-
"requires_python": package["requires_python"] or None,
471+
"requires-python": package["requires_python"] or None,
452472
# data-dist-info-metadata is deprecated alias for core-metadata
453473
"data-dist-info-metadata": (
454474
{"sha256": package["metadata_sha256"]} if package["metadata_sha256"] else False

pulp_python/tests/functional/api/test_pypi_simple_json_api.py

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
import pytest
44
import requests
55

6-
from pulp_python.tests.functional.constants import PYTHON_SM_PROJECT_SPECIFIER
6+
from pulp_python.tests.functional.constants import (
7+
PYTHON_EGG_FILENAME,
8+
PYTHON_EGG_URL,
9+
PYTHON_SM_PROJECT_SPECIFIER,
10+
PYTHON_WHEEL_FILENAME,
11+
PYTHON_WHEEL_URL,
12+
)
713

814
API_VERSION = "1.0"
915
PYPI_SERIAL_CONSTANT = 1000000000
@@ -38,13 +44,21 @@ def test_simple_json_index_api(
3844

3945
@pytest.mark.parallel
4046
def test_simple_json_detail_api(
41-
python_remote_factory, python_repo_with_sync, python_distribution_factory
47+
monitor_task,
48+
python_bindings,
49+
python_content_factory,
50+
python_distribution_factory,
51+
python_repo_factory,
4252
):
43-
remote = python_remote_factory(includes=PYTHON_SM_PROJECT_SPECIFIER)
44-
repo = python_repo_with_sync(remote)
53+
content_1 = python_content_factory(PYTHON_WHEEL_FILENAME, url=PYTHON_WHEEL_URL)
54+
content_2 = python_content_factory(PYTHON_EGG_FILENAME, url=PYTHON_EGG_URL)
55+
body = {"add_content_units": [content_1.pulp_href, content_2.pulp_href]}
56+
57+
repo = python_repo_factory()
58+
monitor_task(python_bindings.RepositoriesPythonApi.modify(repo.pulp_href, body).task)
4559
distro = python_distribution_factory(repository=repo)
4660

47-
url = f'{urljoin(distro.base_url, "simple/")}aiohttp'
61+
url = f'{urljoin(distro.base_url, "simple/")}shelf-reader'
4862
headers = {"Accept": PYPI_SIMPLE_V1_JSON}
4963

5064
response = requests.get(url, headers=headers)
@@ -53,17 +67,32 @@ def test_simple_json_detail_api(
5367

5468
data = response.json()
5569
assert data["meta"] == {"api-version": API_VERSION, "_last-serial": PYPI_SERIAL_CONSTANT}
56-
assert data["name"] == "aiohttp"
70+
assert data["name"] == "shelf-reader"
5771
assert data["files"]
58-
for file in data["files"]:
59-
for i in [
60-
"filename",
61-
"url",
62-
"hashes",
63-
"data-dist-info-metadata",
64-
"requires_python",
65-
]:
66-
assert i in file
72+
73+
# Check data of a wheel
74+
file_whl = next(
75+
(i for i in data["files"] if i["filename"] == "shelf_reader-0.1-py2-none-any.whl"), None
76+
)
77+
assert file_whl is not None, "wheel file not found"
78+
assert file_whl["url"]
79+
assert file_whl["hashes"] == {
80+
"sha256": "2eceb1643c10c5e4a65970baf63bde43b79cbdac7de81dae853ce47ab05197e9"
81+
}
82+
assert file_whl["requires-python"] is None
83+
assert file_whl["data-dist-info-metadata"] == {
84+
"sha256": "ed333f0db05d77e933a157b7225b403ada9a2f93318d77b41b662eba78bac350"
85+
}
86+
87+
# Check data of a tarball
88+
file_tar = next((i for i in data["files"] if i["filename"] == "shelf-reader-0.1.tar.gz"), None)
89+
assert file_tar is not None, "tar file not found"
90+
assert file_tar["url"]
91+
assert file_tar["hashes"] == {
92+
"sha256": "04cfd8bb4f843e35d51bfdef2035109bdea831b55a57c3e6a154d14be116398c"
93+
}
94+
assert file_tar["requires-python"] is None
95+
assert file_tar["data-dist-info-metadata"] is False
6796

6897

6998
@pytest.mark.parallel

0 commit comments

Comments
 (0)