pulp-python 3.30.3__py3-none-any.whl → 3.31.0__py3-none-any.whl

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.
@@ -12,7 +12,7 @@ class PulpPythonPluginAppConfig(PulpPluginAppConfig):
12
12
 
13
13
  name = "pulp_python.app"
14
14
  label = "python"
15
- version = "3.30.3"
15
+ version = "3.31.0"
16
16
  python_package_name = "pulp-python"
17
17
  domain_compatible = True
18
18
 
@@ -0,0 +1,54 @@
1
+ from gettext import gettext as _
2
+
3
+ from pulpcore.plugin.exceptions import PulpException
4
+
5
+
6
+ class AttestationVerificationError(PulpException):
7
+ """
8
+ Raised when attestation verification fails.
9
+ """
10
+
11
+ error_code = "PYT0001"
12
+
13
+ def __init__(self, message):
14
+ super().__init__()
15
+ self.message = message
16
+
17
+ def __str__(self):
18
+ return f"[{self.error_code}] " + _("Attestation verification failed: {message}").format(
19
+ message=self.message
20
+ )
21
+
22
+
23
+ class UnsupportedProtocolError(PulpException):
24
+ """
25
+ Raised when an unsupported protocol is used for syncing.
26
+ """
27
+
28
+ error_code = "PYT0002"
29
+
30
+ def __init__(self, protocol):
31
+ super().__init__()
32
+ self.protocol = protocol
33
+
34
+ def __str__(self):
35
+ return f"[{self.error_code}] " + _(
36
+ "Only HTTP(S) is supported for python syncing, got: {protocol}"
37
+ ).format(protocol=self.protocol)
38
+
39
+
40
+ class InvalidAttestationsError(PulpException):
41
+ """
42
+ Raised when attestation data cannot be validated.
43
+ """
44
+
45
+ error_code = "PYT0003"
46
+
47
+ def __init__(self, message):
48
+ super().__init__()
49
+ self.message = message
50
+
51
+ def __str__(self):
52
+ return f"[{self.error_code}] " + _("Invalid attestations: {message}").format(
53
+ message=self.message
54
+ )
pulp_python/app/models.py CHANGED
@@ -412,16 +412,16 @@ class PythonRepository(Repository, AutoAddObjPermsMixin):
412
412
 
413
413
  def _check_for_package_substitution(self, new_version):
414
414
  """
415
- Raise a ValidationError if newly added packages would replace existing packages that have
416
- the same filename but a different sha256 checksum.
415
+ Raise a ValidationError if newly added packages would replace existing packages
416
+ that have the same filename but a different sha256 checksum.
417
417
  """
418
418
  qs = PythonPackageContent.objects.filter(pk__in=new_version.content)
419
419
  duplicates = collect_duplicates(qs, ("filename",))
420
420
  if duplicates:
421
421
  raise ValidationError(
422
- "Found duplicate packages being added with the same filename but different checksums. " # noqa: E501
423
- "To allow this, set 'allow_package_substitution' to True on the repository. "
424
- f"Conflicting packages: {duplicates}"
422
+ "Found duplicate packages being added with the same filename but different "
423
+ "checksums. To allow this, set 'allow_package_substitution' to True on the "
424
+ f"repository. Conflicting packages: {duplicates}"
425
425
  )
426
426
 
427
427
  def _check_blocklist(self, new_version):
@@ -9,7 +9,8 @@ from django.db.utils import IntegrityError
9
9
  from drf_spectacular.utils import extend_schema_serializer
10
10
  from packaging.requirements import Requirement
11
11
  from packaging.version import InvalidVersion, Version
12
- from pydantic import TypeAdapter, ValidationError
12
+ from pydantic import TypeAdapter
13
+ from pydantic import ValidationError as PydanticValidationError
13
14
  from pypi_attestations import AttestationError
14
15
  from rest_framework import serializers
15
16
 
@@ -387,7 +388,7 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
387
388
  attestations = TypeAdapter(list[Attestation]).validate_json(value)
388
389
  else:
389
390
  attestations = TypeAdapter(list[Attestation]).validate_python(value)
390
- except ValidationError as e:
391
+ except PydanticValidationError as e:
391
392
  raise serializers.ValidationError(_("Invalid attestations: {}").format(e))
392
393
  return attestations
393
394
 
@@ -654,7 +655,7 @@ class PackageProvenanceSerializer(core_serializers.NoArtifactContentUploadSerial
654
655
  try:
655
656
  provenance = Provenance.model_validate_json(data["file"].read())
656
657
  data["provenance"] = provenance.model_dump(mode="json")
657
- except ValidationError as e:
658
+ except PydanticValidationError as e:
658
659
  raise serializers.ValidationError(
659
660
  _("The uploaded provenance is not valid: {}").format(e)
660
661
  )
@@ -1,8 +1,7 @@
1
1
  import asyncio
2
2
  import logging
3
3
  from functools import partial
4
- from gettext import gettext as _
5
- from urllib.parse import urljoin
4
+ from urllib.parse import urljoin, urlparse
6
5
 
7
6
  from aiohttp import ClientError, ClientResponseError
8
7
  from bandersnatch.configuration import BandersnatchConfig
@@ -12,9 +11,9 @@ from lxml.etree import LxmlError
12
11
  from packaging.requirements import Requirement
13
12
  from pypi_attestations import Provenance
14
13
  from pypi_simple import IndexPage
15
- from rest_framework import serializers
16
14
 
17
15
  from pulpcore.plugin.download import HttpDownloader
16
+ from pulpcore.plugin.exceptions import SyncError
18
17
  from pulpcore.plugin.models import Artifact, ProgressReport, Remote, Repository
19
18
  from pulpcore.plugin.stages import (
20
19
  DeclarativeArtifact,
@@ -23,6 +22,7 @@ from pulpcore.plugin.stages import (
23
22
  Stage,
24
23
  )
25
24
 
25
+ from pulp_python.app.exceptions import UnsupportedProtocolError
26
26
  from pulp_python.app.models import (
27
27
  PackageProvenance,
28
28
  PythonPackageContent,
@@ -45,14 +45,14 @@ def sync(remote_pk, repository_pk, mirror):
45
45
  mirror (boolean): True for mirror mode, False for additive mode.
46
46
 
47
47
  Raises:
48
- serializers: ValidationError
48
+ SyncError
49
49
 
50
50
  """
51
51
  remote = PythonRemote.objects.get(pk=remote_pk)
52
52
  repository = Repository.objects.get(pk=repository_pk)
53
53
 
54
54
  if not remote.url:
55
- raise serializers.ValidationError(detail=_("A remote must have a url attribute to sync."))
55
+ raise SyncError("A remote must have a url attribute to sync.")
56
56
 
57
57
  first_stage = PythonBanderStage(remote)
58
58
  DeclarativeVersion(first_stage, repository, mirror).create()
@@ -115,7 +115,8 @@ class PythonBanderStage(Stage):
115
115
  url = self.remote.url.rstrip("/")
116
116
  downloader = self.remote.get_downloader(url=url)
117
117
  if not isinstance(downloader, HttpDownloader):
118
- raise ValueError("Only HTTP(S) is supported for python syncing")
118
+ scheme = urlparse(url).scheme
119
+ raise UnsupportedProtocolError(scheme)
119
120
 
120
121
  async with Master(url, allow_non_https=True) as master:
121
122
  # Replace the session with the remote's downloader session
@@ -4,10 +4,13 @@ from datetime import datetime, timezone
4
4
  from django.contrib.sessions.models import Session
5
5
  from django.db import transaction
6
6
  from pydantic import TypeAdapter
7
+ from pydantic import ValidationError as PydanticValidationError
8
+ from pypi_attestations import AttestationError
7
9
 
8
10
  from pulpcore.plugin.models import Artifact, Content, ContentArtifact, CreatedResource
9
11
  from pulpcore.plugin.util import get_current_authenticated_user, get_domain, get_prn
10
12
 
13
+ from pulp_python.app.exceptions import AttestationVerificationError, InvalidAttestationsError
11
14
  from pulp_python.app.models import PackageProvenance, PythonPackageContent, PythonRepository
12
15
  from pulp_python.app.provenance import (
13
16
  AnyPublisher,
@@ -123,13 +126,19 @@ def create_provenance(package, attestations, domain):
123
126
  Returns:
124
127
  the newly created PackageProvenance
125
128
  """
126
- attestations = TypeAdapter(list[Attestation]).validate_python(attestations)
129
+ try:
130
+ attestations = TypeAdapter(list[Attestation]).validate_python(attestations)
131
+ except PydanticValidationError as e:
132
+ raise InvalidAttestationsError(str(e))
127
133
 
128
134
  user = get_current_authenticated_user()
129
135
  publisher = AnyPublisher(kind="Pulp User", prn=get_prn(user))
130
136
  att_bundle = AttestationBundle(publisher=publisher, attestations=attestations)
131
137
  provenance = Provenance(attestation_bundles=[att_bundle])
132
- verify_provenance(package.filename, package.sha256, provenance)
138
+ try:
139
+ verify_provenance(package.filename, package.sha256, provenance)
140
+ except AttestationError as e:
141
+ raise AttestationVerificationError(str(e))
133
142
  provenance_json = provenance.model_dump(mode="json")
134
143
 
135
144
  prov_sha256 = PackageProvenance.calculate_sha256(provenance_json)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pulp-python
3
- Version: 3.30.3
3
+ Version: 3.31.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
@@ -1,12 +1,13 @@
1
1
  pulp_python/__init__.py,sha256=GIuTLoBTc-07dSLJUh8xrZPRz8x-jJ61pfR0J1IjnzI,65
2
2
  pulp_python/pytest_plugin.py,sha256=LNnLjOkeEu2X4gJi614bHVmbsHyEwooHYIeecr96Qy4,8606
3
- pulp_python/app/__init__.py,sha256=VKkMV6VGzjAXuAn4JdLyxxMWYfMBI9VZcsviliiedEU,2490
3
+ pulp_python/app/__init__.py,sha256=Dh2hJwj55-Hhj1AS-ylzEngH75RptOtCuDTpvanHjhM,2490
4
+ pulp_python/app/exceptions.py,sha256=mPNcWyuzF0XeOPybm-G6oDKtRqvfj4jyp41iaYqcqkA,1314
4
5
  pulp_python/app/global_access_conditions.py,sha256=MZJtyoVsr-4hRaty6mKDqh3caOHd5UKJjEWLV2crOLs,1080
5
6
  pulp_python/app/modelresource.py,sha256=4SFAdqk6lozi_cZz4uqDIqhqPAZF-7l5jJwPn-xGZFs,1249
6
- pulp_python/app/models.py,sha256=Y7MDTl2nKz1dz2S4KQIQQ4oWcYgBA4TyDVxJGBYPHY4,17705
7
+ pulp_python/app/models.py,sha256=oEZ05nKkYzqkMOq2dUJ4QzZlA0-rvwWyxrEHwax91YI,17691
7
8
  pulp_python/app/provenance.py,sha256=iyhkuNahHiTDK0Djrd4-PlgErA5SJVI0uQOIPj46tEI,2352
8
9
  pulp_python/app/replica.py,sha256=qiWRP7tM_v4yP_XLIQfumfGolru-Jt6ZA0KVb-9g2cA,1882
9
- pulp_python/app/serializers.py,sha256=Wg83g7LE9Qkf1S7hkkvG2_EJUi7D12l8UyCA1wmwf-I,33819
10
+ pulp_python/app/serializers.py,sha256=y4WJTMPVKcGlbj98cKTeqWQLCB2kfjkX2hON90_iGDo,33882
10
11
  pulp_python/app/settings.py,sha256=Cyc_p6U0HQjKpyrRL6JFrK3R7RMQJ9MAgNMJCfzPEiA,255
11
12
  pulp_python/app/urls.py,sha256=M2xjQ0j47BwQVpi75QCa5eUnQDcroKv3Cee7UrQ3QcA,1387
12
13
  pulp_python/app/utils.py,sha256=aFBd0llndGiBb6VlvoOvGkD3G3ciWyQierykpqxue_8,27386
@@ -44,8 +45,8 @@ pulp_python/app/pypi/views.py,sha256=F55Zp4GPAQDVk936Szu2ECge8p1-5A160iqzrMDTZGc
44
45
  pulp_python/app/tasks/__init__.py,sha256=lTFpVvpDKbqv9RC0b2RYU8Bo6svDjrA-djt16pADFr8,284
45
46
  pulp_python/app/tasks/publish.py,sha256=bjsJzqJbLu7TF5rLb-UsZMmlNnc_LKw-sdHX9Gcatbw,4334
46
47
  pulp_python/app/tasks/repair.py,sha256=5InzdbjW8y3AC4Vj2PsNLm3wGGTr8D3LcfPw_WA2Fks,12257
47
- pulp_python/app/tasks/sync.py,sha256=LqGQsiSbOQl05H9e7PC830aaLDuQXS1Ql1GiwfrO1Qc,12866
48
- pulp_python/app/tasks/upload.py,sha256=Pclsh6co5hBO6wdxZbGKBUSBV643nd9c2RXQO2Nkdik,5698
48
+ pulp_python/app/tasks/sync.py,sha256=_alhmNMVxEGo6touaXuNMkBZH7gv-zdo_gxUmUyPGHY,12886
49
+ pulp_python/app/tasks/upload.py,sha256=HBOknlsAb0mlE-2dJsalH_8JUZwrKk4AsVibmVJf2aQ,6102
49
50
  pulp_python/app/tasks/vulnerability_report.py,sha256=0cyxNb4048HFUdUlGBA6wYsg-hEMjSfE8mtw05Ct9BQ,1126
50
51
  pulp_python/app/webserver_snippets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
52
  pulp_python/app/webserver_snippets/apache.conf,sha256=3frHSl2YV_8pJPscaFxMVo7HmxGJdb8XVmfdLtCxzoA,97
@@ -77,9 +78,9 @@ pulp_python/tests/functional/assets/shelf-reader-0.1.tar.gz.publish.attestation,
77
78
  pulp_python/tests/functional/assets/shelf_reader-0.1-py2-none-any.whl.publish.attestation,sha256=muTQ8dqYSSdx76DlaPjB1REcNIS-aak-Na0TkASxu8M,10426
78
79
  pulp_python/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
80
  pulp_python/tests/unit/test_models.py,sha256=TBI0yKsrdbnJSPeBFfxSqhXK7zaNvR6qg5JehGH3Pds,229
80
- pulp_python-3.30.3.dist-info/licenses/LICENSE,sha256=2ylvL381vKOhdO-w6zkrOxe9lLNBhRQpo9_0EbHC_HM,18046
81
- pulp_python-3.30.3.dist-info/METADATA,sha256=O3QRZ0GzgXIs45OgII_NKjTkSFVYoo3xmEP3xE_hazc,1744
82
- pulp_python-3.30.3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
83
- pulp_python-3.30.3.dist-info/entry_points.txt,sha256=HvqLEXjw_dS5jqAwnE5JiRZFE6f-y5SRtitKLPml2To,115
84
- pulp_python-3.30.3.dist-info/top_level.txt,sha256=X0hXgXc_bpbiKqVrkt8jD5_QEiQviKbHDwveQcOcJjo,12
85
- pulp_python-3.30.3.dist-info/RECORD,,
81
+ pulp_python-3.31.0.dist-info/licenses/LICENSE,sha256=2ylvL381vKOhdO-w6zkrOxe9lLNBhRQpo9_0EbHC_HM,18046
82
+ pulp_python-3.31.0.dist-info/METADATA,sha256=8-vDJU8B_2GbuEf6SZLVlpYanFBoBpRrzPZZ8-F-v3E,1744
83
+ pulp_python-3.31.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
84
+ pulp_python-3.31.0.dist-info/entry_points.txt,sha256=HvqLEXjw_dS5jqAwnE5JiRZFE6f-y5SRtitKLPml2To,115
85
+ pulp_python-3.31.0.dist-info/top_level.txt,sha256=X0hXgXc_bpbiKqVrkt8jD5_QEiQviKbHDwveQcOcJjo,12
86
+ pulp_python-3.31.0.dist-info/RECORD,,