pulp-python 3.31.2__tar.gz → 3.32.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pulp_python-3.31.2 → pulp_python-3.32.0}/CHANGES.md +46 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/PKG-INFO +2 -2
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/__init__.py +1 -1
- pulp_python-3.32.0/pulp_python/app/cache.py +32 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/pypi/views.py +24 -3
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_pypi_apis.py +4 -3
- pulp_python-3.32.0/pulp_python/tests/functional/api/test_simple_cache.py +101 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python.egg-info/PKG-INFO +2 -2
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python.egg-info/SOURCES.txt +2 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python.egg-info/requires.txt +1 -1
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pyproject.toml +4 -4
- {pulp_python-3.31.2 → pulp_python-3.32.0}/COMMITMENT +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/COPYRIGHT +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/LICENSE +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/MANIFEST.in +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/README.md +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/functest_requirements.txt +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/exceptions.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/global_access_conditions.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/management/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/management/commands/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/management/commands/repair-python-metadata.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0001_initial.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0001_squashed_0010_update_json_field.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0002_pythonpackagecontent_python_version.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0003_new_sync_filters.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0004_DATA_swap_distribution_model.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0005_pythonpackagecontent_sha256.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0006_pythonrepository_autopublish.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0007_pythonpackagecontent_mv-2-1.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0008_pythonpackagecontent_unique_sha256.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0009_pythondistribution_allow_uploads.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0010_update_json_field.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0011_alter_pythondistribution_distribution_ptr_and_more.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0012_add_domain.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0013_add_rbac_permissions.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0014_pythonpackagecontent_dynamic_and_more.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0015_alter_pythonpackagecontent_options.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0016_pythonpackagecontent_metadata_sha256.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0017_pythonpackagecontent_size.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0018_packageprovenance.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0019_create_missing_metadata_artifacts.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0020_pythonpackagecontent_name_normalized.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0021_pythonrepository_upload_duplicate_filenames.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0022_pythonblocklistentry.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/modelresource.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/models.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/provenance.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/pypi/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/pypi/serializers.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/replica.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/serializers.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/settings.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/tasks/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/tasks/publish.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/tasks/repair.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/tasks/sync.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/tasks/upload.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/tasks/vulnerability_report.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/urls.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/utils.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/viewsets.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/webserver_snippets/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/webserver_snippets/apache.conf +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/webserver_snippets/nginx.conf +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/pytest_plugin.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_attestations.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_auto_publish.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_blocklist.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_consume_content.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_crud_content_unit.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_crud_publications.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_crud_remotes.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_domains.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_download_content.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_export_import.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_full_mirror.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_pypi_simple_api.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_rbac.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_repair.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_sync.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_upload.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_vulnerability_report.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/assets/shelf-reader-0.1.tar.gz.publish.attestation +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/assets/shelf_reader-0.1-py2-none-any.whl.publish.attestation +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/constants.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/utils.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/unit/__init__.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/unit/test_models.py +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python.egg-info/dependency_links.txt +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python.egg-info/entry_points.txt +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python.egg-info/top_level.txt +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/setup.cfg +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/test_requirements.txt +0 -0
- {pulp_python-3.31.2 → pulp_python-3.32.0}/unittest_requirements.txt +0 -0
|
@@ -8,6 +8,20 @@
|
|
|
8
8
|
|
|
9
9
|
[//]: # (towncrier release notes start)
|
|
10
10
|
|
|
11
|
+
## 3.32.0 (2026-07-21) {: #3.32.0 }
|
|
12
|
+
|
|
13
|
+
#### Features {: #3.32.0-feature }
|
|
14
|
+
|
|
15
|
+
- Added server-side caching and HTTP cache headers (`Cache-Control`, `ETag`) to Simple API responses.
|
|
16
|
+
[#1254](https://github.com/pulp/pulp_python/issues/1254)
|
|
17
|
+
|
|
18
|
+
#### Bugfixes {: #3.32.0-bugfix }
|
|
19
|
+
|
|
20
|
+
- Fixed a bug where the `python_version` field was not parsed correctly when Pulp workers had hyphens in their name.
|
|
21
|
+
- Fixed provenance sync failing when syncing Pulp-created attestations that use a `Pulp User` publisher.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
11
25
|
## 3.31.2 (2026-07-15) {: #3.31.2 }
|
|
12
26
|
|
|
13
27
|
#### Bugfixes {: #3.31.2-bugfix }
|
|
@@ -135,6 +149,22 @@
|
|
|
135
149
|
|
|
136
150
|
---
|
|
137
151
|
|
|
152
|
+
## 3.27.6 (2026-07-16) {: #3.27.6 }
|
|
153
|
+
|
|
154
|
+
#### Bugfixes {: #3.27.6-bugfix }
|
|
155
|
+
|
|
156
|
+
- Fixed provenance sync failing when syncing Pulp-created attestations that use a `Pulp User` publisher.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 3.27.5 (2026-06-30) {: #3.27.5 }
|
|
161
|
+
|
|
162
|
+
#### Bugfixes {: #3.27.5-bugfix }
|
|
163
|
+
|
|
164
|
+
- Fixed a bug where the `python_version` field was not parsed correctly when Pulp workers had hyphens in their name.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
138
168
|
## 3.27.4 (2026-06-05) {: #3.27.4 }
|
|
139
169
|
|
|
140
170
|
#### Bugfixes {: #3.27.4-bugfix }
|
|
@@ -373,6 +403,14 @@
|
|
|
373
403
|
|
|
374
404
|
---
|
|
375
405
|
|
|
406
|
+
## 3.19.4 (2026-06-30) {: #3.19.4 }
|
|
407
|
+
|
|
408
|
+
#### Bugfixes {: #3.19.4-bugfix }
|
|
409
|
+
|
|
410
|
+
- Fixed a bug where the `python_version` field was not parsed correctly when Pulp workers had hyphens in their name.
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
376
414
|
## 3.19.3 (2026-05-04) {: #3.19.3 }
|
|
377
415
|
|
|
378
416
|
#### Bugfixes {: #3.19.3-bugfix }
|
|
@@ -496,6 +534,14 @@ No significant changes.
|
|
|
496
534
|
|
|
497
535
|
---
|
|
498
536
|
|
|
537
|
+
## 3.13.7 (2026-06-30) {: #3.13.7 }
|
|
538
|
+
|
|
539
|
+
#### Bugfixes {: #3.13.7-bugfix }
|
|
540
|
+
|
|
541
|
+
- Fixed a bug where the `python_version` field was not parsed correctly when Pulp workers had hyphens in their name.
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
499
545
|
## 3.13.6 (2026-04-01) {: #3.13.6 }
|
|
500
546
|
|
|
501
547
|
#### Bugfixes {: #3.13.6-bugfix }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pulp-python
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.32.0
|
|
4
4
|
Summary: pulp-python plugin for the Pulp Project
|
|
5
5
|
Author-email: Pulp Team <pulp-list@redhat.com>
|
|
6
6
|
Project-URL: Homepage, https://pulpproject.org
|
|
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: pulpcore<3.
|
|
23
|
+
Requires-Dist: pulpcore<3.130,>=3.105.0
|
|
24
24
|
Requires-Dist: pkginfo<1.13.0,>=1.12.0
|
|
25
25
|
Requires-Dist: bandersnatch<6.7,>=6.6.0
|
|
26
26
|
Requires-Dist: pypi-simple<2.0,>=1.8.0
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from pulpcore.plugin.cache import CacheKeys, SyncContentCache
|
|
2
|
+
from pulpcore.plugin.util import cache_key
|
|
3
|
+
|
|
4
|
+
ACCEPT_HEADER_KEY = "accept_header"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PythonApiCache(SyncContentCache):
|
|
8
|
+
"""
|
|
9
|
+
Cache for the Simple API.
|
|
10
|
+
|
|
11
|
+
Adds Accept header to the cache key so HTML and JSON responses are cached separately.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, base_key=None):
|
|
15
|
+
keys = (CacheKeys.path, CacheKeys.method, ACCEPT_HEADER_KEY)
|
|
16
|
+
super().__init__(base_key=base_key, keys=keys)
|
|
17
|
+
|
|
18
|
+
def make_key(self, request):
|
|
19
|
+
all_keys = {
|
|
20
|
+
CacheKeys.path: request.path,
|
|
21
|
+
CacheKeys.method: request.method,
|
|
22
|
+
ACCEPT_HEADER_KEY: request.headers.get("accept", ""),
|
|
23
|
+
}
|
|
24
|
+
return ":".join(all_keys[k] for k in self.keys)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def find_base_path_cached(request, cached):
|
|
28
|
+
"""
|
|
29
|
+
Resolve the distribution base_path for use as the Redis cache base_key.
|
|
30
|
+
"""
|
|
31
|
+
path = request.resolver_match.kwargs["path"]
|
|
32
|
+
return cache_key(path)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import hashlib
|
|
1
2
|
import logging
|
|
2
3
|
from datetime import datetime, timedelta, timezone
|
|
3
4
|
from itertools import chain
|
|
@@ -15,9 +16,11 @@ from django.http.response import (
|
|
|
15
16
|
HttpResponseBadRequest,
|
|
16
17
|
HttpResponseForbidden,
|
|
17
18
|
HttpResponseNotFound,
|
|
18
|
-
StreamingHttpResponse,
|
|
19
19
|
)
|
|
20
20
|
from django.shortcuts import redirect
|
|
21
|
+
from django.utils.decorators import method_decorator
|
|
22
|
+
from django.views.decorators.cache import cache_control
|
|
23
|
+
from django.views.decorators.http import condition
|
|
21
24
|
from drf_spectacular.utils import extend_schema
|
|
22
25
|
from dynaconf import settings
|
|
23
26
|
from packaging.utils import canonicalize_name
|
|
@@ -31,6 +34,7 @@ from pulpcore.plugin.util import get_domain, get_url
|
|
|
31
34
|
from pulpcore.plugin.viewsets import OperationPostponedResponse
|
|
32
35
|
|
|
33
36
|
from pulp_python.app import tasks
|
|
37
|
+
from pulp_python.app.cache import PythonApiCache, find_base_path_cached
|
|
34
38
|
from pulp_python.app.models import (
|
|
35
39
|
PackageProvenance,
|
|
36
40
|
PythonDistribution,
|
|
@@ -65,6 +69,17 @@ PYPI_SIMPLE_V1_HTML = "application/vnd.pypi.simple.v1+html"
|
|
|
65
69
|
PYPI_SIMPLE_V1_JSON = "application/vnd.pypi.simple.v1+json"
|
|
66
70
|
|
|
67
71
|
|
|
72
|
+
def _etag_func(request, path, **kwargs):
|
|
73
|
+
"""Compute unquoted ETag for the condition decorator. Returns None if no repo."""
|
|
74
|
+
try:
|
|
75
|
+
distro = PyPIMixin.get_distribution(path)
|
|
76
|
+
repo_ver = PyPIMixin.get_repository_version(distro)
|
|
77
|
+
except Http404:
|
|
78
|
+
return None
|
|
79
|
+
raw = f"{repo_ver.number}:{repo_ver.pulp_created.isoformat()}"
|
|
80
|
+
return hashlib.sha256(raw.encode()).hexdigest()[:16]
|
|
81
|
+
|
|
82
|
+
|
|
68
83
|
class PyPISimpleHTMLRenderer(TemplateHTMLRenderer):
|
|
69
84
|
media_type = PYPI_SIMPLE_V1_HTML
|
|
70
85
|
|
|
@@ -298,6 +313,9 @@ class SimpleView(PackageUploadMixin, ViewSet):
|
|
|
298
313
|
)
|
|
299
314
|
|
|
300
315
|
@extend_schema(summary="Get index simple page")
|
|
316
|
+
@method_decorator(cache_control(max_age=600, public=True))
|
|
317
|
+
@method_decorator(condition(etag_func=_etag_func))
|
|
318
|
+
@PythonApiCache(base_key=find_base_path_cached)
|
|
301
319
|
def list(self, request, path):
|
|
302
320
|
"""Gets the simple api html page for the index."""
|
|
303
321
|
repo_version, content = self.get_rvc()
|
|
@@ -316,9 +334,9 @@ class SimpleView(PackageUploadMixin, ViewSet):
|
|
|
316
334
|
index_data = write_simple_index_json(names)
|
|
317
335
|
return Response(index_data, headers=headers)
|
|
318
336
|
else:
|
|
319
|
-
index_data = write_simple_index(names
|
|
337
|
+
index_data = write_simple_index(names)
|
|
320
338
|
kwargs = {"content_type": media_type, "headers": headers}
|
|
321
|
-
return
|
|
339
|
+
return HttpResponse(index_data, **kwargs)
|
|
322
340
|
|
|
323
341
|
def pull_through_package_simple(self, package, path, remote):
|
|
324
342
|
"""Gets the package's simple page from remote."""
|
|
@@ -355,6 +373,9 @@ class SimpleView(PackageUploadMixin, ViewSet):
|
|
|
355
373
|
}
|
|
356
374
|
|
|
357
375
|
@extend_schema(operation_id="pypi_simple_package_read", summary="Get package simple page")
|
|
376
|
+
@method_decorator(cache_control(max_age=600, public=True))
|
|
377
|
+
@method_decorator(condition(etag_func=_etag_func))
|
|
378
|
+
@PythonApiCache(base_key=find_base_path_cached)
|
|
358
379
|
def retrieve(self, request, path, package):
|
|
359
380
|
"""Retrieves the simple api html/json page for a package."""
|
|
360
381
|
repo_ver, content = self.get_rvc()
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_pypi_apis.py
RENAMED
|
@@ -245,8 +245,9 @@ def test_simple_redirect_with_publications(
|
|
|
245
245
|
assert response.url == str(urljoin(pulp_content_url, f"{distro.base_path}/simple/"))
|
|
246
246
|
|
|
247
247
|
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
def test_pypi_json(
|
|
249
|
+
delete_orphans_pre, python_remote_factory, python_repo_with_sync, python_distribution_factory
|
|
250
|
+
):
|
|
250
251
|
"""Checks the data of `pypi/{package_name}/json` endpoint."""
|
|
251
252
|
remote = python_remote_factory(policy="immediate")
|
|
252
253
|
repo = python_repo_with_sync(remote)
|
|
@@ -260,8 +261,8 @@ def test_pypi_json(python_remote_factory, python_repo_with_sync, python_distribu
|
|
|
260
261
|
assert_pypi_json(response.json())
|
|
261
262
|
|
|
262
263
|
|
|
263
|
-
@pytest.mark.parallel
|
|
264
264
|
def test_pypi_json_content_app(
|
|
265
|
+
delete_orphans_pre,
|
|
265
266
|
python_remote_factory,
|
|
266
267
|
python_repo_with_sync,
|
|
267
268
|
python_publication_factory,
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from urllib.parse import urljoin
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
from pulp_python.tests.functional.constants import (
|
|
7
|
+
PYPI_SIMPLE_V1_HTML,
|
|
8
|
+
PYPI_SIMPLE_V1_JSON,
|
|
9
|
+
PYTHON_SM_PROJECT_SPECIFIER,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.fixture
|
|
14
|
+
def skip_without_cache(pulp_settings):
|
|
15
|
+
"""
|
|
16
|
+
Skip test if server-side caching is not enabled.
|
|
17
|
+
"""
|
|
18
|
+
if not pulp_settings.CACHE_ENABLED:
|
|
19
|
+
pytest.skip("CACHE_ENABLED is not set")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@pytest.fixture
|
|
23
|
+
def synced_distro(
|
|
24
|
+
skip_without_cache,
|
|
25
|
+
python_remote_factory,
|
|
26
|
+
python_repo_with_sync,
|
|
27
|
+
python_distribution_factory,
|
|
28
|
+
):
|
|
29
|
+
"""
|
|
30
|
+
Sync a repo and create a distribution for cache tests.
|
|
31
|
+
"""
|
|
32
|
+
remote = python_remote_factory(includes=PYTHON_SM_PROJECT_SPECIFIER)
|
|
33
|
+
repo = python_repo_with_sync(remote)
|
|
34
|
+
return python_distribution_factory(repository=repo)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@pytest.mark.parallel
|
|
38
|
+
def test_simple_cache_hit_miss_and_headers(synced_distro):
|
|
39
|
+
"""
|
|
40
|
+
First request is a MISS, second is a HIT. Cache headers are present and stable.
|
|
41
|
+
"""
|
|
42
|
+
index_url = urljoin(synced_distro.base_url, "simple/")
|
|
43
|
+
detail_url = f"{index_url}aiohttp"
|
|
44
|
+
|
|
45
|
+
for url in [index_url, detail_url]:
|
|
46
|
+
r1 = requests.get(url)
|
|
47
|
+
assert r1.status_code == 200
|
|
48
|
+
assert r1.headers["X-PULP-CACHE"] == "MISS"
|
|
49
|
+
assert r1.headers["Cache-Control"] == "max-age=600, public"
|
|
50
|
+
assert r1.headers["ETag"].startswith('"') and r1.headers["ETag"].endswith('"')
|
|
51
|
+
|
|
52
|
+
r2 = requests.get(url)
|
|
53
|
+
assert r2.status_code == 200
|
|
54
|
+
assert r2.headers["X-PULP-CACHE"] == "HIT"
|
|
55
|
+
assert r2.headers["Cache-Control"] == r1.headers["Cache-Control"]
|
|
56
|
+
assert r2.headers["ETag"] == r1.headers["ETag"]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@pytest.mark.parallel
|
|
60
|
+
def test_simple_cache_separate_accept_headers(synced_distro):
|
|
61
|
+
"""
|
|
62
|
+
HTML and JSON responses are cached separately.
|
|
63
|
+
"""
|
|
64
|
+
url = urljoin(synced_distro.base_url, "simple/")
|
|
65
|
+
|
|
66
|
+
for header in [PYPI_SIMPLE_V1_HTML, PYPI_SIMPLE_V1_JSON]:
|
|
67
|
+
r = requests.get(url, headers={"Accept": header})
|
|
68
|
+
assert r.status_code == 200
|
|
69
|
+
assert r.headers["X-PULP-CACHE"] == "MISS"
|
|
70
|
+
|
|
71
|
+
for header in [PYPI_SIMPLE_V1_HTML, PYPI_SIMPLE_V1_JSON]:
|
|
72
|
+
r = requests.get(url, headers={"Accept": header})
|
|
73
|
+
assert r.status_code == 200
|
|
74
|
+
assert r.headers["X-PULP-CACHE"] == "HIT"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@pytest.mark.parallel
|
|
78
|
+
def test_simple_cache_etag_conditional_request(synced_distro):
|
|
79
|
+
"""
|
|
80
|
+
Matching If-None-Match returns 304, non-matching returns 200.
|
|
81
|
+
"""
|
|
82
|
+
url = urljoin(synced_distro.base_url, "simple/")
|
|
83
|
+
|
|
84
|
+
r1 = requests.get(url)
|
|
85
|
+
assert r1.status_code == 200
|
|
86
|
+
etag = r1.headers["ETag"]
|
|
87
|
+
cache_control = r1.headers["Cache-Control"]
|
|
88
|
+
|
|
89
|
+
r2 = requests.get(url, headers={"If-None-Match": etag})
|
|
90
|
+
assert r2.status_code == 304
|
|
91
|
+
assert r2.headers["ETag"] == etag
|
|
92
|
+
assert r2.headers["Cache-Control"] == cache_control
|
|
93
|
+
assert "X-PULP-CACHE" not in r2.headers
|
|
94
|
+
assert len(r2.content) == 0
|
|
95
|
+
|
|
96
|
+
r3 = requests.get(url, headers={"If-None-Match": '"old"'})
|
|
97
|
+
assert r3.status_code == 200
|
|
98
|
+
assert r3.headers["ETag"] == etag
|
|
99
|
+
assert r3.headers["Cache-Control"] == cache_control
|
|
100
|
+
assert r3.headers["X-PULP-CACHE"] == "HIT"
|
|
101
|
+
assert len(r3.content) > 0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pulp-python
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.32.0
|
|
4
4
|
Summary: pulp-python plugin for the Pulp Project
|
|
5
5
|
Author-email: Pulp Team <pulp-list@redhat.com>
|
|
6
6
|
Project-URL: Homepage, https://pulpproject.org
|
|
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: pulpcore<3.
|
|
23
|
+
Requires-Dist: pulpcore<3.130,>=3.105.0
|
|
24
24
|
Requires-Dist: pkginfo<1.13.0,>=1.12.0
|
|
25
25
|
Requires-Dist: bandersnatch<6.7,>=6.6.0
|
|
26
26
|
Requires-Dist: pypi-simple<2.0,>=1.8.0
|
|
@@ -17,6 +17,7 @@ pulp_python.egg-info/entry_points.txt
|
|
|
17
17
|
pulp_python.egg-info/requires.txt
|
|
18
18
|
pulp_python.egg-info/top_level.txt
|
|
19
19
|
pulp_python/app/__init__.py
|
|
20
|
+
pulp_python/app/cache.py
|
|
20
21
|
pulp_python/app/exceptions.py
|
|
21
22
|
pulp_python/app/global_access_conditions.py
|
|
22
23
|
pulp_python/app/modelresource.py
|
|
@@ -87,6 +88,7 @@ pulp_python/tests/functional/api/test_pypi_apis.py
|
|
|
87
88
|
pulp_python/tests/functional/api/test_pypi_simple_api.py
|
|
88
89
|
pulp_python/tests/functional/api/test_rbac.py
|
|
89
90
|
pulp_python/tests/functional/api/test_repair.py
|
|
91
|
+
pulp_python/tests/functional/api/test_simple_cache.py
|
|
90
92
|
pulp_python/tests/functional/api/test_sync.py
|
|
91
93
|
pulp_python/tests/functional/api/test_upload.py
|
|
92
94
|
pulp_python/tests/functional/api/test_vulnerability_report.py
|
|
@@ -7,7 +7,7 @@ build-backend = 'setuptools.build_meta'
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "pulp-python"
|
|
10
|
-
version = "3.
|
|
10
|
+
version = "3.32.0"
|
|
11
11
|
description = "pulp-python plugin for the Pulp Project"
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
authors = [
|
|
@@ -26,7 +26,7 @@ classifiers=[
|
|
|
26
26
|
]
|
|
27
27
|
requires-python = ">=3.11"
|
|
28
28
|
dependencies = [
|
|
29
|
-
"pulpcore>=3.105.0,<3.
|
|
29
|
+
"pulpcore>=3.105.0,<3.130",
|
|
30
30
|
"pkginfo>=1.12.0,<1.13.0",
|
|
31
31
|
"bandersnatch>=6.6.0,<6.7",
|
|
32
32
|
"pypi-simple>=1.8.0,<2.0",
|
|
@@ -79,7 +79,7 @@ ignore = [
|
|
|
79
79
|
[tool.bumpversion]
|
|
80
80
|
# This section is managed by the plugin template. Do not edit manually.
|
|
81
81
|
|
|
82
|
-
current_version = "3.
|
|
82
|
+
current_version = "3.32.0"
|
|
83
83
|
commit = false
|
|
84
84
|
tag = false
|
|
85
85
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<alpha>0a)?(?P<patch>\\d+)(\\.(?P<release>[a-z]+))?"
|
|
@@ -125,7 +125,6 @@ filename = "./pyproject.toml"
|
|
|
125
125
|
search = "version = \"{current_version}\""
|
|
126
126
|
replace = "version = \"{new_version}\""
|
|
127
127
|
|
|
128
|
-
|
|
129
128
|
[tool.black]
|
|
130
129
|
line-length = 100
|
|
131
130
|
|
|
@@ -149,6 +148,7 @@ extend-select = [
|
|
|
149
148
|
[tool.ruff.lint.flake8-tidy-imports.banned-api]
|
|
150
149
|
# This section is managed by the plugin template. Do not edit manually.
|
|
151
150
|
"distutils".msg = "The 'distutils' module has been deprecated since Python 3.9."
|
|
151
|
+
"pulpcore.app.settings".msg = "Always import 'settings' from 'django.conf' instead."
|
|
152
152
|
"pulpcore.app".msg = "The 'pulpcore' apis must only be consumed via 'pulpcore.plugin'."
|
|
153
153
|
|
|
154
154
|
[tool.ruff.lint.isort]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0003_new_sync_filters.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0010_update_json_field.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0013_add_rbac_permissions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0018_packageprovenance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/app/migrations/0022_pythonblocklistentry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_attestations.py
RENAMED
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_auto_publish.py
RENAMED
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_blocklist.py
RENAMED
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_consume_content.py
RENAMED
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_crud_content_unit.py
RENAMED
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_crud_publications.py
RENAMED
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_crud_remotes.py
RENAMED
|
File without changes
|
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_download_content.py
RENAMED
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_export_import.py
RENAMED
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_full_mirror.py
RENAMED
|
File without changes
|
{pulp_python-3.31.2 → pulp_python-3.32.0}/pulp_python/tests/functional/api/test_pypi_simple_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|