You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Added repository package catalog and metrics endpoints, plus ``collapse_builds`` and ``base_version`` on the Python package content API. The catalog includes ``last_updated``, ``ordering``, newest-first PEP 440 ``versions``/``latest_releases``, and ``name_normalized`` prefix/substring search (at least 3 characters). A trailing rebuild suffix is ``\.[a-zA-Z]+-[^.]+$`` (for example ``5.3.17.rhlw-00001-n0001`` groups with ``5.3.17``). ``latest_releases[].release`` is that suffix on the newest unit in the group, or empty when the stored version has none. Existing installs pick up access policy for the new actions on migrate unless the policy was customized.
1
+
Added repository package catalog and metrics endpoints, plus `collapse_builds` and `base_version` on the Python package content API.
Copy file name to clipboardExpand all lines: CLAUDE.md
-4Lines changed: 0 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -58,7 +58,3 @@ When patchback fails to cherry-pick a PR into an older branch, you need to manua
58
58
## Contributing
59
59
60
60
When preparing to commit and create a PR you **must** follow our [PR checklist](https://pulpproject.org/pulpcore/docs/dev/guides/pull-request-walkthrough/) Important to note is the AI attribution requirement in our commit messages. Also, note that our changelog entries are markdown.
61
-
62
-
## Catalog `strip_build_suffix` and CI unit tests
63
-
64
-
CI runs unit tests with ``pytest -p no:pulpcore``. Collection must not import Django-backed modules (``pulp_python.app.utils``, ``catalog``, models, viewsets). Keep ``strip_build_suffix``, ``BUILD_SUFFIX_PATTERN``, ``version_sort_key``, ``normalize_package_index_ordering``, and ``normalize_name_normalized_search`` in ``pulp_python/app/versions.py``. The rebuild suffix is the last dot-segment matching POSIX ``\.[a-zA-Z]+-[^.]+$`` (letters, dash, rest of that segment; not hard-coded to ``rhlw``). Python ``re`` and SQL ``REGEXP_REPLACE`` share ``BUILD_SUFFIX_PATTERN``; ``catalog.py`` may import it. Catalog ``latest_releases`` keeps the newest ``pulp_created`` unit per logical version; ``release`` is ``rebuild_release`` of that stored ``version`` (empty when there is no suffix). Catalog ``name_normalized`` prefix/substring filters lowercase the input, use ``LIKE`` (not ``ILIKE``) against the trigram GIN index, and reject values shorter than 3 characters. Simple-index ``DISTINCT ON (name_normalized)`` must ``ORDER BY name_normalized, name`` so the displayed project name is deterministic when metadata names differ (``msg-parser`` vs ``msg_parser``). Without the secondary sort, ``ensure_simple`` can miss the ``msg-parser`` link even though both files were published.
Copy file name to clipboardExpand all lines: docs/user/guides/catalog.md
+33-36Lines changed: 33 additions & 36 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,20 +1,20 @@
1
1
# Browse the package catalog
2
2
3
-
Pulp CLI commands for these endpoints are generated from the OpenAPI spec in a separate package; until that is updated, use HTTP.
3
+
The content API lists **one row per file** (wheel, sdist, and so on). Use the repository
4
+
package catalog when you want **one row per package name**, for example in a UI that
5
+
shows Django once with its versions underneath.
4
6
5
-
The content list (`/pulp/api/v3/content/python/packages/`) returns **one row per distribution file** (wheel, sdist, …). For catalog UIs and automation that need **one row per package name**, plus repository metrics, use the repository package index.
6
-
7
-
These endpoints default to the **latest complete repository version**. `{pulp_id}` is the repository UUID. Pass `repository_version` (HREF or PRN) to read a specific version of that repository.
7
+
Both catalog endpoints default to the repository's latest complete version. Pass
8
+
`repository_version` (HREF or PRN) to read an older snapshot. `{pulp_id}` is the
9
+
repository UUID.
8
10
9
11
## List packages
10
12
11
13
```bash
12
14
http GET "${BASE_ADDR}/pulp/api/v3/repositories/python/python/${REPO_PK}/packages/?limit=10"
13
15
```
14
16
15
-
Pagination `count` is the number of **distinct packages** (`name_normalized`), not files.
16
-
17
-
Each row includes both a simple version list and per-version metadata:
17
+
`count` is the number of distinct packages, not files. Each row looks like:
18
18
19
19
```json
20
20
{
@@ -32,27 +32,24 @@ Each row includes both a simple version list and per-version metadata:
32
32
}
33
33
```
34
34
35
-
`set(versions)` is always the same as `set(latest_releases[].version)`. Both lists are newest-first using PEP 440 version order (`1.10` before `1.9` before `1.2`). There is one `latest_releases` entry per **logical version** (after stripping a trailing rebuild suffix `\.[a-zA-Z]+-[^.]+$`), not per wheel or sdist. A rebuild is the last dot-segment that is letters, a dash, then the rest of that segment (for example `5.3.17.rhlw-00001-n0001` → `5.3.17`). Public and predisclosure files of the same `name_normalized` and logical version collapse to that one row.
36
-
37
-
`version` is that base. `release` is the stripped suffix without the leading dot (`rhlw-00001` or `rhlw-00001-n0001`) of the newest unit (`pulp_created`) in that group, otherwise empty.
38
-
39
-
`created_at` is when that logical version entered the repository: `RepositoryContent.pulp_created` of the selected newest rebuild, falling back to the content unit's `pulp_created`.
40
-
41
-
`last_updated` is when the **package** was last updated in this repository version: the latest `RepositoryContent.pulp_created` among **all** Python package units for that `name_normalized` (any rebuild), falling back to the content unit's `pulp_created`. A rebuild of an older version uploaded yesterday updates `last_updated` even if a newer version number already exists.
35
+
-`versions` is the list of version numbers, newestfirst (PEP 440, so `1.10` before `1.9`).
36
+
-`latest_releases` is the same versions with extra metadata. `release` is filled when
37
+
that version has a rebuild (for example `5.3.17.rhlw-00001` is shown as version
38
+
`5.3.17` with `release``rhlw-00001`); otherwise it is empty.
39
+
-`created_at` is when that version was added to the repository.
40
+
-`last_updated` is when **any** file for the package last changed in this repository
41
+
version, including a rebuild of an older version.
42
42
43
43
### Ordering
44
44
45
-
Default order is `name`. Pass `ordering` to change it:
45
+
Default order is `name`. Allowed fields: `name`, `name_normalized`, `last_updated`.
46
+
Prefix with `-` for descending.
46
47
47
48
```bash
48
-
http GET "${BASE_ADDR}/pulp/api/v3/repositories/python/python/${REPO_PK}/packages/" \
49
-
ordering==name
50
49
http GET "${BASE_ADDR}/pulp/api/v3/repositories/python/python/${REPO_PK}/packages/" \
51
50
ordering==-last_updated
52
51
```
53
52
54
-
Allowed fields: `name`, `name_normalized`, `last_updated`. Prefix with `-` for descending. `last_updated` uses `name` then `name_normalized` as a stable pagination tiebreaker. Unknown fields return 400.
55
-
56
53
### Name search
57
54
58
55
```bash
@@ -62,7 +59,9 @@ http GET "${BASE_ADDR}/pulp/api/v3/repositories/python/python/${REPO_PK}/package
62
59
name_normalized__icontains==http
63
60
```
64
61
65
-
`name_normalized__istartswith` and `name_normalized__icontains` are case-insensitive: the value is lowercased and matched with `LIKE` against already-canonical `name_normalized`. Each requires **at least 3 characters** (shorter values return 400). `name__istartswith` is still `ILIKE` on the original package name and has no minimum length. Name search belongs on this index, not on the flat content list.
62
+
`name_normalized__istartswith` and `name_normalized__icontains` match the PEP 503
63
+
normalized name and require at least 3 characters. `name__istartswith` matches the
64
+
original project name and has no minimum length.
66
65
67
66
## Repository metrics
68
67
@@ -78,21 +77,19 @@ http GET "${BASE_ADDR}/pulp/api/v3/repositories/python/python/${REPO_PK}/metrics
78
77
}
79
78
```
80
79
81
-
Counts use Python package content units in that repository version (not filtered by `packagetype`):
82
-
83
-
| Field | Identity |
84
-
|-------|----------|
85
-
|`package_count`| distinct `name_normalized`|
86
-
|`version_count`| distinct `(name_normalized, base_version)` after rebuild-suffix strip |
87
-
|`build_count`| distinct `(name_normalized, full version)`|
80
+
| Field | Meaning |
81
+
|-------|---------|
82
+
|`package_count`| Distinct packages |
83
+
|`version_count`| Distinct packages × versions (rebuilds of the same version count as one) |
Until rebuild suffixes exist, `version_count` equals `build_count`.
86
+
Until a repository contains rebuilds, `version_count` equals `build_count`.
90
87
91
-
## List versions of a package
88
+
## List files for a package
92
89
93
-
Use the existing content API. Pass `packagetype=sdist`for one representative file per PEP version (retry with`packagetype=bdist_wheel` if a release is wheel-only).
94
-
95
-
`collapse_builds=true` keeps one unit per logical version (`name_normalized` + `base_version`), the one with the latest `pulp_created`. Do not nest rebuilds on this list. Clients can drain Pulp `next` if the page is full.
90
+
Use the content API. `packagetype=sdist`returns one sdist per version (retry with
91
+
`packagetype=bdist_wheel` if a release is wheel-only). `collapse_builds=true` keeps
92
+
the newest rebuild per version so you do not have to page through every rebuild.
96
93
97
94
```bash
98
95
http GET "${BASE_ADDR}/pulp/api/v3/content/python/packages/" \
@@ -102,11 +99,11 @@ http GET "${BASE_ADDR}/pulp/api/v3/content/python/packages/" \
102
99
repository_version=="${LATEST_VERSION_HREF}"
103
100
```
104
101
105
-
Every content row includes `base_version` (stripped version; equal to `version` when there is no suffix).
106
-
107
-
## Get one version
102
+
Each content row includes `base_version`: the version without a rebuild suffix
103
+
(equal to `version` when there is none).
108
104
109
-
Omit `collapse_builds`. Filter with `name`, `version`, and `packagetype=sdist`:
105
+
To fetch a single version, omit `collapse_builds` and filter by `name`, `version`,
106
+
and `packagetype`:
110
107
111
108
```bash
112
109
http GET "${BASE_ADDR}/pulp/api/v3/content/python/packages/" \
0 commit comments