Skip to main content

A simple library to write content to public-inbox repositories

Project description

This is a small library for reading and writing public-inbox v2 repositories. Note, that this is not a suitable replacement for public-inbox in itself – the goal is merely to provide a way to produce and consume public-inbox repositories that can be cloned, indexed and served from an actual public-inbox server running elsewhere.

What it does:

  • adds RFC2822 messages to git repositories compatible with public-inbox

  • supports public-inbox v2 format with automatic epoch management

  • reads messages out of a local public-inbox v2 repository using named cursors, with automatic rebase recovery

What it doesn’t do:

  • fetch, clone, or otherwise synchronize with remote repositories (use git, lei, or rsync for that)

  • parse messages (bytes in, bytes out)

  • anything else

For the public-inbox v2 format, see:

Requirements

The git command must exist and be in your path. Reading features that rely on rebase recovery need git 2.40 or newer for the --since-as-filter flag; ordinary reading and all writing work on any recent git.

Installing

For CLI usage, install with pipx:

pipx install ezpi

For library usage, install with pip:

pip install ezpi

Library usage

This is the simplest usage example:

from email.message import EmailMessage
from ezpi import add_rfc822_v2

msg = EmailMessage()
msg.set_content('Hello world!')
# We must have a Subject: and From: headers at least, in order
# to make a useful git commit with that data
msg['Subject'] = 'My excellent subject'
msg['From'] = 'E.X. Ample <example@example.com'>
# The v2 inbox will be created automatically if it doesn't exist
add_rfc822_v2('/path/to/inbox', msg)

You can also pass bytes instead of an EmailMessage object, but we must be able to run message_from_bytes() on it.

Reading a public-inbox repository

EZPI can also read messages out of a local v2 inbox that you’re keeping in sync yourself (via git pull, lei up, etc). Readers identify themselves with a cursor name; EZPI remembers per-cursor where each reader left off.

import ezpi

# First call seeds the cursor at HEAD and yields nothing.
for epoch, commit, msg_bytes in ezpi.iter_new_messages('/path/to/inbox', 'myapp'):
    pass

# After the repo is refreshed (git pull etc), new messages show up here.
# auto_advance=True persists cursor state after each yielded message.
for epoch, commit, msg_bytes in ezpi.iter_new_messages(
    '/path/to/inbox', 'myapp', auto_advance=True
):
    handle(msg_bytes)

# Backfill the whole history instead of starting at HEAD:
for epoch, commit, msg_bytes in ezpi.iter_new_messages(
    '/path/to/inbox', 'myapp', start='beginning'
):
    handle(msg_bytes)

New epochs are detected automatically on every call. If the repository history is rewritten to delete a message, EZPI detects the stale cursor and transparently relocates it by matching on Message-ID, Subject, and commit date.

ezpi command

We also provide an ezpi command. Example:

ezpi --v2-path /path/to/inbox --rfc822 < valid.eml

Run ezpi --help for full usage information.

How to delete messages?

Since every message is a separate commit to the git repository, deleting requires a git history rewrite. You will need to find the commit with the message you want to delete and perform operations directly on the git repository in order to delete that commit and rebase the ones that follow. Once it’s done, you will need to force-push the repository to wherever it is hosted.

Caution: if anyone is replicating your repository without –mirror, the history rewrite will result in an error the next time they do “git remote update”. Needless to say, they will be very interested in finding out what it is you just tried to delete, so use this as the last resort solution.

Support

For support or with any other questions, please email tools@kernel.org, or browse the list archive at https://lore.kernel.org/tools.

Please send patches to tools@kernel.org.

Submissions must be made under the terms of the Linux Foundation certificate of contribution and should include a Signed-off-by: line. Please read the DCO file for full legal definition of what that implies.

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

ezpi-0.6.tar.gz (37.1 kB view details)

Uploaded Source

Built Distribution

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

ezpi-0.6-py3-none-any.whl (20.7 kB view details)

Uploaded Python 3

File details

Details for the file ezpi-0.6.tar.gz.

File metadata

  • Download URL: ezpi-0.6.tar.gz
  • Upload date:
  • Size: 37.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ezpi-0.6.tar.gz
Algorithm Hash digest
SHA256 436312cd3761bc0274dfac5ffe12e6ca505ecaa2906b02036a9ceeb2c00a5f15
MD5 866843aebf12f3cc867c99294d5a4338
BLAKE2b-256 c5d1176b414e0031a0a8856868eff0e74c7517fa4c1004d2da53ea527166b30f

See more details on using hashes here.

File details

Details for the file ezpi-0.6-py3-none-any.whl.

File metadata

  • Download URL: ezpi-0.6-py3-none-any.whl
  • Upload date:
  • Size: 20.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ezpi-0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 26c8e2637f3c9757aa8f3cc88734ef8089509522ce1047442c5f0998645d569d
MD5 5f8a744df6e6d8643911ca831508f300
BLAKE2b-256 a301ce6ef2a64c4af2e3116008253d14dee8a339fcd94b7e9fd05601745251f7

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