Skip to main content

Modern web UI plugin for devpi-server — drop-in replacement for devpi-web

Project description

devpi-admin

A modern web UI plugin for devpi-server — a drop-in replacement for devpi-web. Ships as a Python package that registers itself as a devpi-server plugin via the standard entry point mechanism, so a single pip install devpi-admin is enough.

The UI itself is a bundled single-page application (pure HTML + CSS + vanilla JavaScript, no build step) served under /+admin/. All devpi REST API endpoints remain untouched — the SPA talks to the standard devpi JSON API directly.

Features

Dashboard

  • Server info with version of devpi-server and all installed plugins (auto-detected)
  • Cache metrics with hit-rate bars (storage, changelog, relpath caches)
  • Whoosh search index queue status
  • Replica status (master only) — per-replica cards with online/offline badge, serial lag, and last-seen timestamp; visible only when replicas are connected

Indexes

  • Visual cards color-coded by type: green (stage), amber (volatile stage), blue (mirror)
  • pip install command with copy-to-clipboard (click to copy, green flash feedback)
  • pip.conf toggle — switch between short form and full --index-url / --trusted-host
  • pip.conf generator — download a ready-to-use config per index
  • Create / edit / delete indexes via modal dialogs
  • bases editor with drag & drop priority ordering and transitive inheritance display
  • acl_upload tag picker with user selection dropdown
  • volatile, mirror_url, title configuration

Users

  • Create, edit (email, password), delete users (admin only)

Packages

  • Client-side search with PEP 503 name normalization
  • Mirror indexes: shows only cached packages (filesystem scan, no 17 MB index download); "Download full index" button available for complete browse
  • Package cards with latest version and pip install command

Package detail (PyPI-like layout)

  • Sidebar: metadata (author, license, Python version, keywords, platform, maintainer, extras, project URLs, dependencies), pip install command, file downloads with upload dates
  • Version list: cached versions shown normally, uncached versions link to pypi.org (↗); "Load all versions" button for mirrors
  • README: rendered markdown (via marked.js); fetched from PyPI.org for mirror packages where devpi doesn't cache the description

General

  • Anonymous browsing — visitors can explore public indexes without logging in; admin actions (create/edit/delete) appear only after authentication
  • Dark / light / auto theme with half-circle icon for auto mode
  • Responsive mobile menu with hamburger toggle
  • ESC + outside-click dismissal for modals, dropdown menus, mobile menu
  • Login via modal — no separate login page

Plugin API endpoints

In addition to serving the SPA, devpi-admin registers custom API endpoints under /+admin-api/ for features that the standard devpi REST API doesn't provide efficiently:

Endpoint Method Description
/+admin-api/cached/{user}/{index} GET List cached package names for a mirror index (filesystem scan)
/+admin-api/versions/{user}/{index}/{project} GET Version list with cached/uncached distinction
/+admin-api/versions/{user}/{index}/{project}?all=1 GET Include all upstream versions (mirrors)
/+admin-api/versiondata/{user}/{index}/{project}/{version} GET Metadata + file links for a single version

Installation

pip install devpi-admin

This pulls in devpi-server as a dependency. If you are using devpi in a dedicated venv (recommended), install the plugin into the same venv:

/var/lib/pypi/venv/bin/pip install devpi-admin
systemctl --user restart devpi      # or however you run devpi-server

You should uninstall devpi-webdevpi-admin replaces it entirely:

pip uninstall devpi-web

Both plugins can technically coexist but it is not recommended. devpi-admin intercepts / for HTML requests while devpi-web would still serve its own HTML on other routes like /<user>/<index>/<package>, leading to a confusing mixed experience.

Usage

After restart, open:

http://<your-devpi-host>:3141/

Browser visits to / are redirected to /+admin/, which serves the SPA. Direct links like http://<host>:3141/+admin/#packages/ci/testing work and can be bookmarked.

devpi CLI tools and other JSON clients are unaffected — they send Accept: application/json and bypass the redirect.

How it works

devpi-admin registers a devpi_server entry point that hooks into devpiserver_pyramid_configure (with @hookimpl from pluggy) to:

  1. Serve the bundled static assets under /+admin/ via a Pyramid static view.
  2. Add an explicit view at /+admin/ that returns index.html.
  3. Register custom API views under /+admin-api/ for cached-package and per-version queries.
  4. Install a tween that redirects HTML browser requests on / to /+admin/ while leaving JSON requests intact.

The plugin uses devpi-server internals (xom.model.getstage, stage.list_versions, stage.get_versiondata, stage.get_releaselinks) and direct filesystem access (serverdir/+files/) for the cached-packages API.

Requirements

  • Python 3.9+
  • devpi-server 6.0+
  • A browser with ES6 support (Promise, fetch, sessionStorage)

Routes (UI)

Routing is hash-based, so any of these URLs can be bookmarked or shared:

Hash View
# Status dashboard (default)
#indexes All indexes
#indexes/<user> Indexes filtered by user
#packages/<user>/<index> Packages in an index
#package/<user>/<index>/<name> Package detail (latest cached version)
#package/<user>/<index>/<name>?version=<ver> Specific version
#users User management (requires login)

Project layout

devpi-admin/
├── pyproject.toml
├── README.md
├── LICENSE
├── .github/workflows/
│   ├── tests.yml            — CI on push/PR (Python 3.10 + 3.14)
│   └── publish.yml          — publish to PyPI on release
├── src/
│   └── devpi_admin/
│       ├── __init__.py      — version (from git tag via hatch-vcs)
│       ├── main.py          — Pyramid hooks, tween, API views
│       └── static/
│           ├── index.html   — SPA entry point
│           ├── css/style.css
│           └── js/
│               ├── api.js       — devpi REST wrapper + auth
│               ├── theme.js     — theme toggle (light/dark/auto)
│               ├── marked.min.js  — vendored markdown renderer
│               └── app.js       — routing, views, rendering
└── tests/
    ├── test_cached_versions.py  — filesystem scan (tmpdir)
    ├── test_helpers.py          — filename parsing, normalization
    ├── test_hooks.py            — pluggy hook registration
    ├── test_json_safe.py        — readonly view conversion
    ├── test_package.py          — entry point, static files
    ├── test_tween.py            — redirect behavior
    └── test_wants_html.py       — Accept header heuristic

Development

git clone <repo>
cd devpi-admin
python -m venv .venv
.venv/bin/pip install -e .

The static files live at src/devpi_admin/static/ and can be edited in place — changes show up on the next browser reload, no restart of devpi-server required (static views read from disk on each request). Python changes (main.py) require a devpi-server restart.

Run the unit tests:

PYTHONWARNINGS="ignore::UserWarning" python -m unittest discover -v tests/

(The PYTHONWARNINGS shim hides an unrelated deprecation warning emitted by Pyramid 2.1 when it imports pkg_resources.)

Releasing

Version is derived from the git tag via hatch-vcs. To release:

  1. git tag v0.1.0 && git push --tags
  2. On GitHub: Releases → Draft new release → select tag → Publish
  3. The publish.yml workflow runs tests, builds wheel+sdist, and uploads to PyPI via trusted publishing (no API tokens needed — configure the GitHub environment pypi in PyPI settings).

Author

Pavel Revak pavelrevak@gmail.com

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

devpi_admin-1.2.0.tar.gz (57.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

devpi_admin-1.2.0-py3-none-any.whl (49.1 kB view details)

Uploaded Python 3

File details

Details for the file devpi_admin-1.2.0.tar.gz.

File metadata

  • Download URL: devpi_admin-1.2.0.tar.gz
  • Upload date:
  • Size: 57.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for devpi_admin-1.2.0.tar.gz
Algorithm Hash digest
SHA256 f477cfe3c394f7db17e5b7bec051733da50d80c66ea04f7224bd96d2eab3e81e
MD5 db122e5bb575535595b6ecf473af3e3a
BLAKE2b-256 51dd5b890eb48b9be6a779eeeb69155ad2957005e47b18f62beae0885d8a96d8

See more details on using hashes here.

Provenance

The following attestation bundles were made for devpi_admin-1.2.0.tar.gz:

Publisher: publish.yml on pavelrevak/devpi-admin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file devpi_admin-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: devpi_admin-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 49.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for devpi_admin-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4f6654dd335a172b47f734ca16c40d0e1d48b43241921b4eb18e87bbc7c48b60
MD5 f3eac849333c1e5302b32750241f6aa7
BLAKE2b-256 13b06f89e9ab844d478d43b863eaff3936666e3c980bd2da1e836c440aa36ae8

See more details on using hashes here.

Provenance

The following attestation bundles were made for devpi_admin-1.2.0-py3-none-any.whl:

Publisher: publish.yml on pavelrevak/devpi-admin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page