Skip to main content

Comicbox

PyPI Python License Docs

Comicbox is a Python library and command line tool that reads, writes, and synthesizes comic book archive metadata. It understands every popular comic metadata standard, merges them into one consistent data model, converts between them, tags comics from online databases, and extracts pages and covers.

It is the metadata engine behind the Codex comic reader, but works just as well as a standalone command line tool for organizing a comic library.

✨ What Comicbox Does

  • Reads many archive types — CBZ, CBR, CBT, CB7, and (optionally) PDF.
  • Reads and writes every popular metadata standard — ComicInfo.xml, MetronInfo.xml, ComicBookInfo, CoMet, PDF metadata, and its own YAML/JSON.
  • Merges every source into one model — combines metadata from each embedded format and the filename into a single normalized view, then writes it back out to whichever formats you choose.
  • Tags comics online — looks up and matches comics against Metron and ComicVine, then writes the result.
  • Converts archives — repacks CBR/CBT/CB7 (and comic PDFs) to CBZ, and translates metadata between formats.
  • Extracts images — pulls cover art or arbitrary page ranges out of any supported archive.
  • Is scriptable and embeddable — a rich CLI, a Python API, and published JSON Schemas for every format.

📚 Archive Formats

Format Read Write
CBZ (zip)
CBR (rar) converts to CBZ
CBT (tar) converts to CBZ
CB7 (7z) converts to CBZ
PDF ✅ embedded metadata

CBR extraction and conversion require the unrar binary on your PATH. PDF support is an optional extra.

🏷️ Metadata Formats

Comicbox reads and writes all of the following, normalizing each into a common schema:

Format Read Write Notes
ComicInfo.xml (ComicRack) v2.1 (draft) schema
MetronInfo.xml v1.1 schema
ComicBookInfo (Comic Book Lover) archive comment JSON
CoMet
PDF metadata can embed ComicInfo.xml / MetronInfo.xml
Comicbox YAML / JSON native, lossless
Filename parses metadata out of the file name

A full cross-format tag translation table is available.

🔀 One Unified Metadata Model

Different formats spell the same idea in different ways. Comicbox reconciles them so you never have to:

  • Identifiers — IDs, GTINs, and URLs from every format are aggregated into a single identifiers structure, and written back out as URNs in the Notes field.
  • Reprints — Alternate Names, Aliases, and "is version of" relationships collapse into one reprints list.
  • Notes mining — the heavily-abused Notes field is parsed for embedded data (tagger, timestamps, and identifiers) that formats don't otherwise carry.
  • Liberal value parsing — fuzzy, caseless values for enum-like fields (Age Rating, Format, credit roles) are accepted, tidied to Title Case, and converted to each output format's own enum on write.
  • Filename parsing — series, issue, year, and more are extracted from a wide variety of naming conventions via comicfn2dict.

🌐 Online Tagging

Comicbox can identify a comic and tag it from an online database. Metron and ComicVine are supported. It searches by the series, issue, and year it knows about, ranks candidates, breaks close calls with cover-image matching, and writes the best result.

# Interactive: prompts only when the match isn't clear.
comicbox --online metron "GI Joe #007 (1952).cbz"

# Tag by an exact database id (skips searching).
comicbox --id metron:42 "comic.cbz"

# Unattended batch run: never prompts, 4 files at a time.
comicbox --online all --recurse --prompts never -j 4 ./comics/

--match controls how confidently comicbox writes without asking (ask · careful · auto · eager), and --effort (minimal · balanced · thorough) trades matching accuracy for fewer API calls on fan-out sources like ComicVine — Metron doesn't fan out, so it ignores effort and always searches at full strength. Credentials come from --auth, COMICBOX_* environment variables, the config file, or your system keyring. See comicbox -h for the full set of online, caching, and tuning options.

🖼️ Pages, Covers & Conversion

# Extract the cover image.
comicbox --extract-covers --dest-path ./out "comic.cbz"

# Extract a range of pages (zero-based) by index.
comicbox --extract-pages 0:5 --dest-path ./out "comic.cbz"

# Convert a CBR to a CBZ, carrying metadata across.
comicbox --cbz "comic.cbr"

# Convert a single-image-per-page comic PDF to CBZ without re-encoding.
comicbox --cbz --pdf-pages image "comic.pdf"

# Rename a file to comicbox's canonical filename format.
comicbox --rename "comic.cbz"

📦 Installation

pip install comicbox

For PDF support, install the pdf extra:

pip install comicbox[pdf]

Dependencies

Comicbox needs no binary dependencies for CBZ, CBT, and CB7. Reading or converting CBR archives requires the unrar binary on your PATH.

The optional PDF extra pulls in pymupdf, which ships wheels with a bundled libmupdf for most platforms. Some platforms (e.g. Linux on ARM) may need libstdc++ plus C/C++ build tools to compile it.

Installing on ARM (AARCH64)

pymupdf has no pre-built AARCH64 wheels, so pip must build it. On some Python versions the build fails unless this environment variable is set:

PYMUPDF_SETUP_PY_LIMITED_API=0 pip install comicbox[pdf]

You will also need the build-essential and python3-dev (or equivalent) packages.

⌨️ Command Line

Comicbox ships a thorough, self-documenting CLI. Run:

comicbox -h

for the complete reference, including every metadata format key, the --print phases, and the online tagging tables. A few representative commands:

# Print the merged metadata comicbox reads from a comic.
comicbox -p "comic.cbz"

# Set a field and write it as ComicInfo.xml inside the archive.
comicbox -m "{publisher: SmallComics}" -w cix "comic.cbz"

# Recursively set a field across an entire library.
comicbox --recurse -m "{publisher: 'SC Comics'}" -w cix ./comics/

# Export and re-import metadata as a file.
comicbox --export cix "comic.cbz"
comicbox --import ComicInfo.xml -w cix "comic.cbz"

-m/--metadata accepts a compact "linear YAML" using tag names from any of the supported formats. Put a space after each colon so it parses as YAML, and quote values containing YAML special characters (:[]{},). See comicbox -h for many more -m examples, and "escaping YAML" for the escaping details.

💡 Preview before writing. Add -p to print exactly what would be written, or -n/--dry-run to perform an action without touching the filesystem.

Editing or Deleting Metadata

The cleanest way to edit or remove existing tags is to round-trip through a file:

# 1. Export the current metadata to an editable file.
comicbox --export cix "My Overtagged Comic.cbz"

# 2. Edit it.
nvim ComicInfo.xml

# 3. Preview the re-import.
comicbox --import ComicInfo.xml -p "My Overtagged Comic.cbz"

# 4. Wipe the old tags, then write the edited file back (careful!).
comicbox --delete-all-tags "My Overtagged Comic.cbz"
comicbox --import ComicInfo.xml -w cix "My Overtagged Comic.cbz"

You can also drop individual keys with -D/--delete-keys using dotted glom paths, e.g. -D series,reprints.0.series.

🛠 API

Comicbox is primarily a library. The Comicbox class in comicbox.box is the main read interface, and comicbox.write exposes a documented write API. Auto-generated API docs are published with the HTML docs.

from comicbox.box import Comicbox

with Comicbox("comic.cbz") as cb:
    metadata = cb.to_dict()  # merged, normalized metadata
    file_type = cb.get_file_type()  # "CBZ", "PDF", ...
    mtime = cb.get_metadata_mtime()  # last metadata modification time
    cover = cb.get_cover_page()  # cover image bytes

Writing is done through the public write_metadata (single file) and bulk_write (batched) helpers:

from comicbox.write import write_metadata

result = write_metadata(
    "comic.cbz",
    # The patch is the contents under the "comicbox" root tag. The
    # root-wrapped dict Comicbox.to_dict() returns is also accepted.
    {"publisher": {"name": "SmallComics"}, "genres": ["Science Fiction"]},
    formats=["COMIC_INFO"],  # MetadataFormats names; e.g. COMIC_INFO, METRON_INFO
)
print(result.written)

Every operational error these APIs raise derives from comicbox.exceptions.ComicboxErrorArchiveError, ArchiveWriteError, MetadataError, ExportError, WriteValidationError, OnlineConfigurationError, OnlineLookupAbortedError, and UnsupportedArchiveTypeError — so consumers can except ComicboxError without swallowing unrelated programming errors.

⚙️ Configuration

Comicbox is configured by command line arguments, an optional config file, and environment variables (in that order of precedence).

  • Defaults live in config_default.yaml, which also documents the nested config groups (general, read, write, convert, compute, and online).
  • Config file — point at one with -c PATH, or place it at ~/.config/comicbox/config.yaml.
  • Environment variables are prefixed with COMICBOX_.
  • Log level is set with the LOGLEVEL environment variable:
LOGLEVEL=ERROR comicbox -p "comic.cbz"

📦 Related Packages

Installing comicbox also installs two small sibling libraries, each usable on its own:

  • comicfn2dict — parses metadata out of comic filenames into Python dicts (also used by ComicTagger).
  • pdffile — presents a ZipFile-like interface for PDF files (installed with the [pdf] extra).

📜 Documentation

🛠 Development

Comicbox is hosted on GitHub. Most development tasks are driven by the Makefile — run make to see what's available.

The DEBUG_TRANSFORM environment variable prints verbose schema-transform information, useful when debugging format conversions.

📄 License

Comicbox is licensed under the LGPL-3.0-only license.

Download files

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

Source Distribution

comicbox-4.6.1.tar.gz (1.0 MB view details)

Uploaded Source

Built Distribution

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

comicbox-4.6.1-py3-none-any.whl (342.8 kB view details)

Uploaded Python 3

File details

Details for the file comicbox-4.6.1.tar.gz.

File metadata

  • Download URL: comicbox-4.6.1.tar.gz
  • Upload date:
  • Size: 1.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","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 comicbox-4.6.1.tar.gz
Algorithm Hash digest
SHA256 4a4f50df0143c21853356a8defa767335434d870da6cdc6c56fef9a77c1f8c87
MD5 c35453403af8417d0aeeede11eb24e9e
BLAKE2b-256 6e051c2369de5b000c963fa119c2515d3fd1c64e55fa518eca2b691a86315c26

See more details on using hashes here.

File details

Details for the file comicbox-4.6.1-py3-none-any.whl.

File metadata

  • Download URL: comicbox-4.6.1-py3-none-any.whl
  • Upload date:
  • Size: 342.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","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 comicbox-4.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8d4c288f775063858620679dd0e4b61291ef14180fbc24767adf5b15684208f7
MD5 a4d5e1c3a74ac8fdd5641fc5c6bdbded
BLAKE2b-256 cf246acdbbc6c3ef7bb9023bbeb586d442649218f72177e3013b26a0b1dadc3e

See more details on using hashes here.

Release history Release notifications | RSS feed

4.8.7

2 files

4.8.6

2 files

4.8.5

2 files

4.8.4

2 files

4.8.3

2 files

4.8.2

2 files

4.8.1

2 files

4.8.0

2 files

4.7.1

2 files

4.7.0

2 files

This release

4.6.1 This release

2 files

4.6.0

2 files

4.5.1

2 files

4.5.0

2 files

4.4.0

2 files

4.3.0

2 files

4.2.0

2 files

4.1.1

2 files

4.1.0

2 files

4.0.5

2 files

4.0.4

2 files

4.0.3

2 files

4.0.2

2 files

4.0.1

2 files

4.0.0

2 files

3.0.3

2 files

3.0.2

2 files

3.0.1

2 files

3.0.0

2 files

2.2.3

2 files

2.2.2

2 files

2.2.1

2 files

2.2.0

2 files

2.1.1

2 files

2.1.0

2 files

2.0.6

2 files

2.0.5

2 files

2.0.4

2 files

2.0.3

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.2.3

2 files

1.2.1

2 files

1.2.0

2 files

1.1.10

2 files

1.1.9

2 files

1.1.8

2 files

1.1.7

2 files

1.1.6

2 files

1.1.5

2 files

1.1.4

2 files

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.0

2 files

0.10.1

2 files

0.10.0

2 files

0.9.1

2 files

0.9.0

2 files

0.8.0

2 files

0.7.1

2 files

0.7.0

2 files

0.6.7

2 files

0.6.6

2 files

0.6.5

2 files

0.6.4

2 files

0.6.3

2 files

0.6.2

2 files

0.6.1

1 file

0.6.0

2 files

0.5.5

2 files

0.5.4

2 files

0.5.3

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.1

2 files

0.4.0

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page