Skip to main content

auntiepypi — both ends of the Python distribution pipe for the AgentCulture mesh.

Project description

auntiepypi

auntie (Python distribution: auntiepypi) is both a CLI and an agent that maintains, uses, and serves the CLI for managing PyPI packages. It overviews packages on pypi.org, detects PyPI-flavored servers running locally, and starts/stops/restarts declared servers — informational first, actionable on demand.

Status: v0.8.0 — auntie publish (write side) landed. The first-party server now accepts twine-compatible POST uploads at / (legacy PyPI upload protocol — multipart/form-data with :action=file_upload). Authorization is gated by both v0.7.0 auth AND a new publish_users allowlist; empty allowlist preserves read-only mode. New CLI verb auntie publish <path> reads creds from $AUNTIE_PUBLISH_USER / $AUNTIE_PUBLISH_PASSWORD or interactive prompt. Per-request body cap via [tool.auntiepypi.local].max_upload_bytes (default 100 MiB). No new runtime dep.

Bare auntie up / auntie down / auntie restart (introduced in v0.6.0) continue to start, stop, and restart auntie's own simple-index server. Wheels in $XDG_DATA_HOME/auntiepypi/wheels/ are served from http://127.0.0.1:3141/simple/ (or https://... when TLS is configured) and installable via pip install --index-url. Lifecycle verbs continue to work against declared servers (managed_by ∈ {systemd-user, command}); --all aggregates the first-party server with every supervised declaration.

Quick start

uv tool install auntiepypi
auntie --version
auntie overview --json | jq '.sections[] | select(.category == "servers")'
auntie overview requests            # deep-dive into a PyPI package
auntie doctor                       # diagnose declared servers (dry-run)
auntie doctor --apply               # act on actionable remediations
auntie up                           # start the first-party PEP 503 server
auntie up <name>                    # start one declared server
auntie up --all                     # first-party server + every supervised declaration
auntie down                         # stop the first-party server
auntie restart <name>               # atomic for systemd-user; stop+start for command
AUNTIE_PUBLISH_USER=alice \
AUNTIE_PUBLISH_PASSWORD=secret \
  auntie publish dist/mypkg-1.0.whl  # upload via twine-compatible POST (v0.8.0)

Example servers-section output (one declared server):

{
  "category": "servers",
  "title": "main",
  "light": "green",
  "fields": [
    {"name": "flavor", "value": "pypiserver"},
    {"name": "port",   "value": "8080"},
    {"name": "status", "value": "up"},
    {"name": "source", "value": "declared"}
  ]
}

For the overview and doctor to show anything, add the relevant blocks to your repo's pyproject.toml:

[tool.auntiepypi]
packages = ["requests", "pip"]
scan_processes = false             # opt into /proc scan; same as `--proc`

[[tool.auntiepypi.servers]]
name = "main"
flavor = "pypiserver"
port = 8080
managed_by = "systemd-user"
unit = "pypi-server.service"

# v0.7.0: HTTPS + Basic auth on the first-party server.
# Loopback host (127.0.0.1, ::1, localhost) is always allowed.
# Non-loopback host requires BOTH cert+key AND htpasswd.
# v0.8.0: publish_users gates the POST upload endpoint; empty list
# preserves read-only mode. max_upload_bytes caps per-request body.
[tool.auntiepypi.local]
host = "0.0.0.0"
cert = "/etc/ssl/private/auntie.pem"
key  = "/etc/ssl/private/auntie.key"
htpasswd = "/etc/auntie/htpasswd"      # bcrypt-only; populate via `htpasswd -B`
publish_users = ["alice", "bob"]       # v0.8.0: who can POST uploads
max_upload_bytes = 104857600           # v0.8.0: 100 MiB default

Publishing a wheel (v0.8.0)

# Operator: configure auth + publish_users (above), then start the server.
auntie up

# Publisher: build a wheel and upload via auntie's CLI.
uv build
AUNTIE_PUBLISH_USER=alice AUNTIE_PUBLISH_PASSWORD=secret \
  auntie publish dist/mypkg-1.0-py3-none-any.whl
# expect: "published mypkg-1.0-py3-none-any.whl → /files/..."

# Or via twine — the server speaks the legacy PyPI upload protocol.
TWINE_USERNAME=alice TWINE_PASSWORD=secret \
  twine upload --repository-url https://0.0.0.0:3141/ dist/*.whl

Self-signed certs need AUNTIE_INSECURE_SKIP_VERIFY=1 (loud stderr warning fires on each invocation). Existing-file uploads return 409 (no overwrite, ever — pick a new version).

pip + Basic auth note. pip install --index-url https://user:pass@host:port/simple/ works but embeds creds in URL, leaking them in process listings and pip's debug output. keyring integration is the long-term answer; in the meantime, an environment- scoped per-user pip.conf (path resolves via python -m pip config debug) reduces exposure.

auntie doctor walkthrough

auntie doctor classifies every known server into one of four categories and explains exactly what to do next:

$ auntie doctor
# auntie doctor
summary: 1 actionable, 1 half-supervised, 1 skip, 0 ambiguous (3 total)

  main          down     declared    managed_by=command
      diagnosis: down; would dispatch managed_by='command'
      remediation: auntie doctor --apply

  stale         down     declared    managed_by=systemd-user
      config_gap: managed_by="systemd-user" requires `unit`
      diagnosis: half-supervised; --apply would delete this entry
      remediation: add `unit = "…"` to keep supervision, or run `auntie doctor --apply`

  pypiserver:8080  up    port        observed; not declared
      remediation:
          [[tool.auntiepypi.servers]]
          name = "…"
          flavor = "pypiserver"
          port = 8080
          managed_by = "manual"

(dry-run; pass --apply to act on 2 remediations)

Pass --apply to act. A numbered snapshot is written before any edit:

$ auntie doctor --apply
wrote pyproject.toml.1.bak (rollback: mv pyproject.toml.1.bak pyproject.toml)
...

If two entries share the same name, use --decide to choose which to keep (or remove):

$ auntie doctor --apply --decide=duplicate:main=1
wrote pyproject.toml.1.bak (rollback: mv pyproject.toml.1.bak pyproject.toml)
wrote pyproject.toml: removed [[tool.auntiepypi.servers]] entry 'main' occurrence 1 (lines 7-12)
...

See docs/about.md for the longer non-technical explainer. systemd-user unit templates for pypiserver / devpi-server live in docs/deploy/.

Develop

uv sync                          # install + dev deps
uv run pytest -n auto -v         # tests
uv run auntie --version          # smoke
uv run pre-commit install        # enable lint hooks

Quality pipeline mirrors the rest of the AgentCulture mesh: black, isort, flake8 (+ flake8-bandit, flake8-bugbear), pylint, bandit, markdownlint-cli2. CI runs on every PR + push to main.

Trusted Publishing

ghafi provisions the pypi / testpypi GitHub Environments and .github/workflows/publish.yml follows the same OIDC Trusted Publishing pattern every sibling uses — no secrets in the repo.

License

MIT. © 2026 Ori Nachum / AgentCulture.

— Claude

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

auntiepypi-0.8.0.tar.gz (357.4 kB view details)

Uploaded Source

Built Distribution

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

auntiepypi-0.8.0-py3-none-any.whl (114.4 kB view details)

Uploaded Python 3

File details

Details for the file auntiepypi-0.8.0.tar.gz.

File metadata

  • Download URL: auntiepypi-0.8.0.tar.gz
  • Upload date:
  • Size: 357.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for auntiepypi-0.8.0.tar.gz
Algorithm Hash digest
SHA256 4ccba2068352316f58745384522b64312e22a3f292801cea30727efefe9b0f9b
MD5 4a5e35f8d6c0ff2bc57b223c17ee9f05
BLAKE2b-256 f9e3ea30105ecf178504667b834a1ecf19d3a7bc2f4dc290593cf2baeeccf629

See more details on using hashes here.

File details

Details for the file auntiepypi-0.8.0-py3-none-any.whl.

File metadata

  • Download URL: auntiepypi-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 114.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for auntiepypi-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d1d888220b6bf08ae1468a4fcd81845f9a624ab7e413d1dbce0773f7c504dbcf
MD5 c4ff879943790ce322b8a4aecd3b5eac
BLAKE2b-256 8b9a63fc686b2adb500b9871703bf974d3ac617a84f3c15c412dfb831151a5a5

See more details on using hashes here.

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