pulp-python 3.13.6__py3-none-any.whl → 3.13.7__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.
Files changed (38) hide show
  1. pulp_python/__init__.py +1 -1
  2. pulp_python/app/__init__.py +5 -3
  3. pulp_python/app/global_access_conditions.py +0 -1
  4. pulp_python/app/management/commands/repair-python-metadata.py +5 -4
  5. pulp_python/app/modelresource.py +1 -0
  6. pulp_python/app/models.py +8 -7
  7. pulp_python/app/pypi/serializers.py +11 -9
  8. pulp_python/app/pypi/views.py +69 -54
  9. pulp_python/app/replica.py +3 -2
  10. pulp_python/app/serializers.py +187 -110
  11. pulp_python/app/settings.py +1 -1
  12. pulp_python/app/tasks/publish.py +24 -25
  13. pulp_python/app/tasks/sync.py +15 -29
  14. pulp_python/app/tasks/upload.py +7 -8
  15. pulp_python/app/urls.py +5 -5
  16. pulp_python/app/utils.py +52 -45
  17. pulp_python/app/viewsets.py +43 -46
  18. pulp_python/pytest_plugin.py +14 -5
  19. pulp_python/tests/functional/api/test_consume_content.py +0 -1
  20. pulp_python/tests/functional/api/test_crud_content_unit.py +8 -5
  21. pulp_python/tests/functional/api/test_crud_publications.py +9 -6
  22. pulp_python/tests/functional/api/test_crud_remotes.py +3 -2
  23. pulp_python/tests/functional/api/test_domains.py +9 -7
  24. pulp_python/tests/functional/api/test_download_content.py +2 -2
  25. pulp_python/tests/functional/api/test_export_import.py +7 -4
  26. pulp_python/tests/functional/api/test_full_mirror.py +4 -4
  27. pulp_python/tests/functional/api/test_pypi_apis.py +13 -18
  28. pulp_python/tests/functional/api/test_rbac.py +6 -5
  29. pulp_python/tests/functional/api/test_repair.py +3 -2
  30. pulp_python/tests/functional/api/test_sync.py +28 -19
  31. pulp_python/tests/functional/constants.py +15 -33
  32. pulp_python/tests/functional/utils.py +15 -6
  33. {pulp_python-3.13.6.dist-info → pulp_python-3.13.7.dist-info}/METADATA +1 -1
  34. {pulp_python-3.13.6.dist-info → pulp_python-3.13.7.dist-info}/RECORD +38 -38
  35. {pulp_python-3.13.6.dist-info → pulp_python-3.13.7.dist-info}/WHEEL +0 -0
  36. {pulp_python-3.13.6.dist-info → pulp_python-3.13.7.dist-info}/entry_points.txt +0 -0
  37. {pulp_python-3.13.6.dist-info → pulp_python-3.13.7.dist-info}/licenses/LICENSE +0 -0
  38. {pulp_python-3.13.6.dist-info → pulp_python-3.13.7.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  from gettext import gettext as _
2
+
2
3
  from django.conf import settings
3
4
  from packaging.requirements import Requirement
4
5
  from rest_framework import serializers
@@ -44,15 +45,14 @@ class PythonDistributionSerializer(core_serializers.DistributionSerializer):
44
45
  )
45
46
  base_url = serializers.SerializerMethodField(read_only=True)
46
47
  allow_uploads = serializers.BooleanField(
47
- default=True,
48
- help_text=_("Allow packages to be uploaded to this index.")
48
+ default=True, help_text=_("Allow packages to be uploaded to this index.")
49
49
  )
50
50
  remote = core_serializers.DetailRelatedField(
51
51
  required=False,
52
- help_text=_('Remote that can be used to fetch content when using pull-through caching.'),
52
+ help_text=_("Remote that can be used to fetch content when using pull-through caching."),
53
53
  view_name_pattern=r"remotes(-.*/.*)?-detail",
54
54
  queryset=core_models.Remote.objects.all(),
55
- allow_null=True
55
+ allow_null=True,
56
56
  )
57
57
 
58
58
  def get_base_url(self, obj):
@@ -63,7 +63,9 @@ class PythonDistributionSerializer(core_serializers.DistributionSerializer):
63
63
 
64
64
  class Meta:
65
65
  fields = core_serializers.DistributionSerializer.Meta.fields + (
66
- 'publication', "allow_uploads", "remote"
66
+ "publication",
67
+ "allow_uploads",
68
+ "remote",
67
69
  )
68
70
  model = python_models.PythonDistribution
69
71
 
@@ -74,126 +76,162 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
74
76
  """
75
77
 
76
78
  filename = serializers.CharField(
77
- help_text=_('The name of the distribution package, usually of the format:'
78
- ' {distribution}-{version}(-{build tag})?-{python tag}-{abi tag}'
79
- '-{platform tag}.{packagetype}'),
79
+ help_text=_(
80
+ "The name of the distribution package, usually of the format:"
81
+ " {distribution}-{version}(-{build tag})?-{python tag}-{abi tag}"
82
+ "-{platform tag}.{packagetype}"
83
+ ),
80
84
  read_only=True,
81
85
  )
82
86
  packagetype = serializers.CharField(
83
- help_text=_('The type of the distribution package '
84
- '(e.g. sdist, bdist_wheel, bdist_egg, etc)'),
87
+ help_text=_(
88
+ "The type of the distribution package (e.g. sdist, bdist_wheel, bdist_egg, etc)"
89
+ ),
85
90
  read_only=True,
86
91
  )
87
92
  name = serializers.CharField(
88
- help_text=_('The name of the python project.'),
93
+ help_text=_("The name of the python project."),
89
94
  read_only=True,
90
95
  )
91
96
  version = serializers.CharField(
92
- help_text=_('The packages version number.'),
97
+ help_text=_("The packages version number."),
93
98
  read_only=True,
94
99
  )
95
100
  sha256 = serializers.CharField(
96
- default='',
97
- help_text=_('The SHA256 digest of this package.'),
101
+ default="",
102
+ help_text=_("The SHA256 digest of this package."),
98
103
  )
99
104
  metadata_version = serializers.CharField(
100
- help_text=_('Version of the file format'),
105
+ help_text=_("Version of the file format"),
101
106
  read_only=True,
102
107
  )
103
108
  summary = serializers.CharField(
104
- required=False, allow_blank=True,
105
- help_text=_('A one-line summary of what the package does.')
109
+ required=False,
110
+ allow_blank=True,
111
+ help_text=_("A one-line summary of what the package does."),
106
112
  )
107
113
  description = serializers.CharField(
108
- required=False, allow_blank=True,
109
- help_text=_('A longer description of the package that can run to several paragraphs.')
114
+ required=False,
115
+ allow_blank=True,
116
+ help_text=_("A longer description of the package that can run to several paragraphs."),
110
117
  )
111
118
  description_content_type = serializers.CharField(
112
- required=False, allow_blank=True,
113
- help_text=_('A string stating the markup syntax (if any) used in the distribution’s'
114
- ' description, so that tools can intelligently render the description.')
119
+ required=False,
120
+ allow_blank=True,
121
+ help_text=_(
122
+ "A string stating the markup syntax (if any) used in the distribution’s"
123
+ " description, so that tools can intelligently render the description."
124
+ ),
115
125
  )
116
126
  keywords = serializers.CharField(
117
- required=False, allow_blank=True,
118
- help_text=_('Additional keywords to be used to assist searching for the '
119
- 'package in a larger catalog.')
127
+ required=False,
128
+ allow_blank=True,
129
+ help_text=_(
130
+ "Additional keywords to be used to assist searching for the "
131
+ "package in a larger catalog."
132
+ ),
120
133
  )
121
134
  home_page = serializers.CharField(
122
- required=False, allow_blank=True,
123
- help_text=_('The URL for the package\'s home page.')
135
+ required=False, allow_blank=True, help_text=_("The URL for the package's home page.")
124
136
  )
125
137
  download_url = serializers.CharField(
126
- required=False, allow_blank=True,
127
- help_text=_('Legacy field denoting the URL from which this package can be downloaded.')
138
+ required=False,
139
+ allow_blank=True,
140
+ help_text=_("Legacy field denoting the URL from which this package can be downloaded."),
128
141
  )
129
142
  author = serializers.CharField(
130
- required=False, allow_blank=True,
131
- help_text=_('Text containing the author\'s name. Contact information can also be added,'
132
- ' separated with newlines.')
143
+ required=False,
144
+ allow_blank=True,
145
+ help_text=_(
146
+ "Text containing the author's name. Contact information can also be added,"
147
+ " separated with newlines."
148
+ ),
133
149
  )
134
150
  author_email = serializers.CharField(
135
- required=False, allow_blank=True,
136
- help_text=_('The author\'s e-mail address. ')
151
+ required=False, allow_blank=True, help_text=_("The author's e-mail address. ")
137
152
  )
138
153
  maintainer = serializers.CharField(
139
- required=False, allow_blank=True,
140
- help_text=_('The maintainer\'s name at a minimum; '
141
- 'additional contact information may be provided.')
154
+ required=False,
155
+ allow_blank=True,
156
+ help_text=_(
157
+ "The maintainer's name at a minimum; additional contact information may be provided."
158
+ ),
142
159
  )
143
160
  maintainer_email = serializers.CharField(
144
- required=False, allow_blank=True,
145
- help_text=_('The maintainer\'s e-mail address.')
161
+ required=False, allow_blank=True, help_text=_("The maintainer's e-mail address.")
146
162
  )
147
163
  license = serializers.CharField(
148
- required=False, allow_blank=True,
149
- help_text=_('Text indicating the license covering the distribution')
164
+ required=False,
165
+ allow_blank=True,
166
+ help_text=_("Text indicating the license covering the distribution"),
150
167
  )
151
168
  requires_python = serializers.CharField(
152
- required=False, allow_blank=True,
153
- help_text=_('The Python version(s) that the distribution is guaranteed to be '
154
- 'compatible with.')
169
+ required=False,
170
+ allow_blank=True,
171
+ help_text=_(
172
+ "The Python version(s) that the distribution is guaranteed to be compatible with."
173
+ ),
155
174
  )
156
175
  project_url = serializers.CharField(
157
- required=False, allow_blank=True,
158
- help_text=_('A browsable URL for the project and a label for it, separated by a comma.')
176
+ required=False,
177
+ allow_blank=True,
178
+ help_text=_("A browsable URL for the project and a label for it, separated by a comma."),
159
179
  )
160
180
  project_urls = serializers.JSONField(
161
- required=False, default=dict,
162
- help_text=_('A dictionary of labels and URLs for the project.')
181
+ required=False,
182
+ default=dict,
183
+ help_text=_("A dictionary of labels and URLs for the project."),
163
184
  )
164
185
  platform = serializers.CharField(
165
- required=False, allow_blank=True,
166
- help_text=_('A comma-separated list of platform specifications, '
167
- 'summarizing the operating systems supported by the package.')
186
+ required=False,
187
+ allow_blank=True,
188
+ help_text=_(
189
+ "A comma-separated list of platform specifications, "
190
+ "summarizing the operating systems supported by the package."
191
+ ),
168
192
  )
169
193
  supported_platform = serializers.CharField(
170
- required=False, allow_blank=True,
171
- help_text=_('Field to specify the OS and CPU for which the binary package was compiled. ')
194
+ required=False,
195
+ allow_blank=True,
196
+ help_text=_("Field to specify the OS and CPU for which the binary package was compiled. "),
172
197
  )
173
198
  requires_dist = serializers.JSONField(
174
- required=False, default=list,
175
- help_text=_('A JSON list containing names of some other distutils project '
176
- 'required by this distribution.')
199
+ required=False,
200
+ default=list,
201
+ help_text=_(
202
+ "A JSON list containing names of some other distutils project "
203
+ "required by this distribution."
204
+ ),
177
205
  )
178
206
  provides_dist = serializers.JSONField(
179
- required=False, default=list,
180
- help_text=_('A JSON list containing names of a Distutils project which is contained'
181
- ' within this distribution.')
207
+ required=False,
208
+ default=list,
209
+ help_text=_(
210
+ "A JSON list containing names of a Distutils project which is contained"
211
+ " within this distribution."
212
+ ),
182
213
  )
183
214
  obsoletes_dist = serializers.JSONField(
184
- required=False, default=list,
185
- help_text=_('A JSON list containing names of a distutils project\'s distribution which '
186
- 'this distribution renders obsolete, meaning that the two projects should not '
187
- 'be installed at the same time.')
215
+ required=False,
216
+ default=list,
217
+ help_text=_(
218
+ "A JSON list containing names of a distutils project's distribution which "
219
+ "this distribution renders obsolete, meaning that the two projects should not "
220
+ "be installed at the same time."
221
+ ),
188
222
  )
189
223
  requires_external = serializers.JSONField(
190
- required=False, default=list,
191
- help_text=_('A JSON list containing some dependency in the system that the distribution '
192
- 'is to be used.')
224
+ required=False,
225
+ default=list,
226
+ help_text=_(
227
+ "A JSON list containing some dependency in the system that the distribution "
228
+ "is to be used."
229
+ ),
193
230
  )
194
231
  classifiers = serializers.JSONField(
195
- required=False, default=list,
196
- help_text=_('A JSON list containing classification values for a Python package.')
232
+ required=False,
233
+ default=list,
234
+ help_text=_("A JSON list containing classification values for a Python package."),
197
235
  )
198
236
 
199
237
  def deferred_validate(self, data):
@@ -212,22 +250,26 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
212
250
  try:
213
251
  filename = data["relative_path"]
214
252
  except KeyError:
215
- raise serializers.ValidationError(detail={"relative_path": _('This field is required')})
253
+ raise serializers.ValidationError(detail={"relative_path": _("This field is required")})
216
254
 
217
255
  artifact = data["artifact"]
218
256
  try:
219
257
  _data = artifact_to_python_content_data(filename, artifact, domain=get_domain())
220
258
  except ValueError:
221
- raise serializers.ValidationError(_(
222
- "Extension on {} is not a valid python extension "
223
- "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)").format(filename)
259
+ raise serializers.ValidationError(
260
+ _(
261
+ "Extension on {} is not a valid python extension "
262
+ "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)"
263
+ ).format(filename)
224
264
  )
225
265
 
226
266
  if data.get("sha256") and data["sha256"] != artifact.sha256:
227
267
  raise serializers.ValidationError(
228
- detail={"sha256": _(
229
- "The uploaded artifact's sha256 checksum does not match the one provided"
230
- )}
268
+ detail={
269
+ "sha256": _(
270
+ "The uploaded artifact's sha256 checksum does not match the one provided"
271
+ )
272
+ }
231
273
  )
232
274
 
233
275
  data.update(_data)
@@ -242,11 +284,33 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
242
284
 
243
285
  class Meta:
244
286
  fields = core_serializers.SingleArtifactContentUploadSerializer.Meta.fields + (
245
- 'filename', 'packagetype', 'name', 'version', 'sha256', 'metadata_version', 'summary',
246
- 'description', 'description_content_type', 'keywords', 'home_page', 'download_url',
247
- 'author', 'author_email', 'maintainer', 'maintainer_email', 'license',
248
- 'requires_python', 'project_url', 'project_urls', 'platform', 'supported_platform',
249
- 'requires_dist', 'provides_dist', 'obsoletes_dist', 'requires_external', 'classifiers'
287
+ "filename",
288
+ "packagetype",
289
+ "name",
290
+ "version",
291
+ "sha256",
292
+ "metadata_version",
293
+ "summary",
294
+ "description",
295
+ "description_content_type",
296
+ "keywords",
297
+ "home_page",
298
+ "download_url",
299
+ "author",
300
+ "author_email",
301
+ "maintainer",
302
+ "maintainer_email",
303
+ "license",
304
+ "requires_python",
305
+ "project_url",
306
+ "project_urls",
307
+ "platform",
308
+ "supported_platform",
309
+ "requires_dist",
310
+ "provides_dist",
311
+ "obsoletes_dist",
312
+ "requires_external",
313
+ "classifiers",
250
314
  )
251
315
  model = python_models.PythonPackageContent
252
316
 
@@ -258,7 +322,11 @@ class MinimalPythonPackageContentSerializer(PythonPackageContentSerializer):
258
322
 
259
323
  class Meta:
260
324
  fields = core_serializers.SingleArtifactContentUploadSerializer.Meta.fields + (
261
- 'filename', 'packagetype', 'name', 'version', 'sha256',
325
+ "filename",
326
+ "packagetype",
327
+ "name",
328
+ "version",
329
+ "sha256",
262
330
  )
263
331
  model = python_models.PythonPackageContent
264
332
 
@@ -282,47 +350,49 @@ class PythonRemoteSerializer(core_serializers.RemoteSerializer):
282
350
  child=serializers.CharField(allow_blank=False),
283
351
  required=False,
284
352
  allow_empty=True,
285
- help_text=_(
286
- "A list containing project specifiers for Python packages to include."
287
- ),
353
+ help_text=_("A list containing project specifiers for Python packages to include."),
288
354
  )
289
355
  excludes = serializers.ListField(
290
356
  child=serializers.CharField(allow_blank=False),
291
357
  required=False,
292
358
  allow_empty=True,
293
- help_text=_(
294
- "A list containing project specifiers for Python packages to exclude."
295
- ),
359
+ help_text=_("A list containing project specifiers for Python packages to exclude."),
296
360
  )
297
361
  prereleases = serializers.BooleanField(
298
- required=False,
299
- help_text=_('Whether or not to include pre-release packages in the sync.')
362
+ required=False, help_text=_("Whether or not to include pre-release packages in the sync.")
300
363
  )
301
364
  policy = serializers.ChoiceField(
302
- help_text=_("The policy to use when downloading content. The possible values include: "
303
- "'immediate', 'on_demand', and 'streamed'. 'on_demand' is the default."),
365
+ help_text=_(
366
+ "The policy to use when downloading content. The possible values include: "
367
+ "'immediate', 'on_demand', and 'streamed'. 'on_demand' is the default."
368
+ ),
304
369
  choices=core_models.Remote.POLICY_CHOICES,
305
- default=core_models.Remote.ON_DEMAND
370
+ default=core_models.Remote.ON_DEMAND,
306
371
  )
307
372
  package_types = MultipleChoiceArrayField(
308
373
  required=False,
309
- help_text=_("The package types to sync for Python content. Leave blank to get every"
310
- "package type."),
374
+ help_text=_(
375
+ "The package types to sync for Python content. Leave blank to get everypackage type."
376
+ ),
311
377
  choices=python_models.PACKAGE_TYPES,
312
- default=list
378
+ default=list,
313
379
  )
314
380
  keep_latest_packages = serializers.IntegerField(
315
381
  required=False,
316
- help_text=_("The amount of latest versions of a package to keep on sync, includes"
317
- "pre-releases if synced. Default 0 keeps all versions."),
318
- default=0
382
+ help_text=_(
383
+ "The amount of latest versions of a package to keep on sync, includes"
384
+ "pre-releases if synced. Default 0 keeps all versions."
385
+ ),
386
+ default=0,
319
387
  )
320
388
  exclude_platforms = MultipleChoiceArrayField(
321
389
  required=False,
322
- help_text=_("List of platforms to exclude syncing Python packages for. Possible values"
323
- "include: windows, macos, freebsd, and linux."),
390
+ help_text=_(
391
+ "List of platforms to exclude syncing Python packages for. Possible values"
392
+ "include: windows, macos, freebsd, and linux."
393
+ ),
324
394
  choices=python_models.PLATFORMS,
325
- default=list
395
+ default=list,
326
396
  )
327
397
 
328
398
  def validate_includes(self, value):
@@ -332,7 +402,7 @@ class PythonRemoteSerializer(core_serializers.RemoteSerializer):
332
402
  Requirement(pkg)
333
403
  except ValueError as ve:
334
404
  raise serializers.ValidationError(
335
- _("includes specifier {} is invalid. {}".format(pkg, ve))
405
+ _("includes specifier {} is invalid. {}").format(pkg, ve)
336
406
  )
337
407
  return value
338
408
 
@@ -343,13 +413,17 @@ class PythonRemoteSerializer(core_serializers.RemoteSerializer):
343
413
  Requirement(pkg)
344
414
  except ValueError as ve:
345
415
  raise serializers.ValidationError(
346
- _("excludes specifier {} is invalid. {}".format(pkg, ve))
416
+ _("excludes specifier {} is invalid. {}").format(pkg, ve)
347
417
  )
348
418
  return value
349
419
 
350
420
  class Meta:
351
421
  fields = core_serializers.RemoteSerializer.Meta.fields + (
352
- "includes", "excludes", "prereleases", "package_types", "keep_latest_packages",
422
+ "includes",
423
+ "excludes",
424
+ "prereleases",
425
+ "package_types",
426
+ "keep_latest_packages",
353
427
  "exclude_platforms",
354
428
  )
355
429
  model = python_models.PythonRemote
@@ -371,10 +445,12 @@ class PythonBanderRemoteSerializer(serializers.Serializer):
371
445
  )
372
446
 
373
447
  policy = serializers.ChoiceField(
374
- help_text=_("The policy to use when downloading content. The possible values include: "
375
- "'immediate', 'on_demand', and 'streamed'. 'on_demand' is the default."),
448
+ help_text=_(
449
+ "The policy to use when downloading content. The possible values include: "
450
+ "'immediate', 'on_demand', and 'streamed'. 'on_demand' is the default."
451
+ ),
376
452
  choices=core_models.Remote.POLICY_CHOICES,
377
- default=core_models.Remote.ON_DEMAND
453
+ default=core_models.Remote.ON_DEMAND,
378
454
  )
379
455
 
380
456
 
@@ -384,8 +460,9 @@ class PythonPublicationSerializer(core_serializers.PublicationSerializer):
384
460
  """
385
461
 
386
462
  distributions = core_serializers.DetailRelatedField(
387
- help_text=_('This publication is currently being hosted as configured by these '
388
- 'distributions.'),
463
+ help_text=_(
464
+ "This publication is currently being hosted as configured by these distributions."
465
+ ),
389
466
  source="distribution_set",
390
467
  view_name="pythondistributions-detail",
391
468
  many=True,
@@ -393,5 +470,5 @@ class PythonPublicationSerializer(core_serializers.PublicationSerializer):
393
470
  )
394
471
 
395
472
  class Meta:
396
- fields = core_serializers.PublicationSerializer.Meta.fields + ('distributions',)
473
+ fields = core_serializers.PublicationSerializer.Meta.fields + ("distributions",)
397
474
  model = python_models.PythonPublication
@@ -1,7 +1,7 @@
1
1
  import socket
2
2
 
3
3
  PYTHON_GROUP_UPLOADS = False
4
- PYPI_API_HOSTNAME = 'https://' + socket.getfqdn()
4
+ PYPI_API_HOSTNAME = "https://" + socket.getfqdn()
5
5
 
6
6
  DRF_ACCESS_POLICY = {
7
7
  "dynaconf_merge_unique": True,
@@ -1,6 +1,6 @@
1
- from gettext import gettext as _
2
1
  import logging
3
2
  import os
3
+ from gettext import gettext as _
4
4
 
5
5
  from django.core.files import File
6
6
  from packaging.utils import canonicalize_name
@@ -9,8 +9,7 @@ from pulpcore.plugin import models
9
9
  from pulpcore.plugin.util import get_domain
10
10
 
11
11
  from pulp_python.app import models as python_models
12
- from pulp_python.app.utils import write_simple_index, write_simple_detail
13
-
12
+ from pulp_python.app.utils import write_simple_detail, write_simple_index
14
13
 
15
14
  log = logging.getLogger(__name__)
16
15
 
@@ -25,15 +24,17 @@ def publish(repository_version_pk):
25
24
  """
26
25
  repository_version = models.RepositoryVersion.objects.get(pk=repository_version_pk)
27
26
 
28
- log.info(_('Publishing: repository={repo}, version={version}').format(
29
- repo=repository_version.repository.name,
30
- version=repository_version.number,
31
- ))
27
+ log.info(
28
+ _("Publishing: repository={repo}, version={version}").format(
29
+ repo=repository_version.repository.name,
30
+ version=repository_version.number,
31
+ )
32
+ )
32
33
 
33
34
  with python_models.PythonPublication.create(repository_version, pass_through=True) as pub:
34
35
  write_simple_api(pub)
35
36
 
36
- log.info(_('Publication: {pk} created').format(pk=pub.pk))
37
+ log.info(_("Publication: {pk} created").format(pk=pub.pk))
37
38
  return pub
38
39
 
39
40
 
@@ -51,26 +52,24 @@ def write_simple_api(publication):
51
52
 
52
53
  """
53
54
  domain = get_domain()
54
- simple_dir = 'simple/'
55
+ simple_dir = "simple/"
55
56
  os.mkdir(simple_dir)
56
57
  project_names = (
57
58
  python_models.PythonPackageContent.objects.filter(
58
59
  pk__in=publication.repository_version.content, _pulp_domain=domain
59
60
  )
60
- .order_by('name')
61
- .values_list('name', flat=True)
61
+ .order_by("name")
62
+ .values_list("name", flat=True)
62
63
  .distinct()
63
64
  )
64
65
 
65
66
  # write the root index, which lists all of the projects for which there is a package available
66
- index_path = '{simple_dir}index.html'.format(simple_dir=simple_dir)
67
- with open(index_path, 'w') as index:
67
+ index_path = "{simple_dir}index.html".format(simple_dir=simple_dir)
68
+ with open(index_path, "w") as index:
68
69
  index.write(write_simple_index(project_names))
69
70
 
70
71
  index_metadata = models.PublishedMetadata.create_from_file(
71
- relative_path=index_path,
72
- publication=publication,
73
- file=File(open(index_path, 'rb'))
72
+ relative_path=index_path, publication=publication, file=File(open(index_path, "rb"))
74
73
  )
75
74
  index_metadata.save()
76
75
 
@@ -86,41 +85,41 @@ def write_simple_api(publication):
86
85
  current_name = project_names[ind]
87
86
  package_releases = []
88
87
  for release in releases.iterator():
89
- if release['name'] != current_name:
88
+ if release["name"] != current_name:
90
89
  write_project_page(
91
90
  name=canonicalize_name(current_name),
92
91
  simple_dir=simple_dir,
93
92
  package_releases=package_releases,
94
- publication=publication
93
+ publication=publication,
95
94
  )
96
95
  package_releases = []
97
96
  ind += 1
98
97
  current_name = project_names[ind]
99
- relative_path = release['filename']
98
+ relative_path = release["filename"]
100
99
  path = f"../../{relative_path}"
101
- checksum = release['sha256']
100
+ checksum = release["sha256"]
102
101
  package_releases.append((relative_path, path, checksum))
103
102
  # Write the final project's page
104
103
  write_project_page(
105
104
  name=canonicalize_name(current_name),
106
105
  simple_dir=simple_dir,
107
106
  package_releases=package_releases,
108
- publication=publication
107
+ publication=publication,
109
108
  )
110
109
 
111
110
 
112
111
  def write_project_page(name, simple_dir, package_releases, publication):
113
112
  """Writes a project's simple page."""
114
- project_dir = f'{simple_dir}{name}/'
113
+ project_dir = f"{simple_dir}{name}/"
115
114
  os.mkdir(project_dir)
116
- metadata_relative_path = f'{project_dir}index.html'
115
+ metadata_relative_path = f"{project_dir}index.html"
117
116
 
118
- with open(metadata_relative_path, 'w') as simple_metadata:
117
+ with open(metadata_relative_path, "w") as simple_metadata:
119
118
  simple_metadata.write(write_simple_detail(name, package_releases))
120
119
 
121
120
  project_metadata = models.PublishedMetadata.create_from_file(
122
121
  relative_path=metadata_relative_path,
123
122
  publication=publication,
124
- file=File(open(metadata_relative_path, 'rb'))
123
+ file=File(open(metadata_relative_path, "rb")),
125
124
  )
126
125
  project_metadata.save() # change to bulk create when multi-table supported