Skip to main content

Metron API Best Practices

· 9 min read
Brian Pepple
Founder of the Metron Project / Code Monkey

The Metron API gives developers programmatic access to a comprehensive comic book database — publishers, series, issues, characters, creators, story arcs, and more. To keep it fast and available for everyone, a little care in how you use it goes a long way. This post covers the patterns that will make your integration both efficient and a good citizen on the platform.

March 2026 News

· 9 min read
Brian Pepple
Founder of the Metron Project / Code Monkey

Monthly Statistics

During March the Metron Project added the following to its database:

  • Users: 164
  • Issues: 1,107
  • Creators: 36
  • Characters: 240

Thanks to everyone that contributed!

API Rate Limit Reduction

Early in March, we reduced the API rate limits due to increased server load from growing API usage. The new limits are:

  • 20 requests per minute (down from 30)
  • 5,000 requests per day (down from 10,000)

Updated releases of Mokkari and Metron-Tagger were published to reflect these changes. If you consume the API directly, make sure your code handles HTTP 429 responses and respects the Retry-After header. If we receive enough donations to cover a server upgrade, we would look at restoring the daily limit to 10,000 requests per day.

Website

Here's a summary of everything that landed in the website since the start of March, covering API improvements, reading list enhancements, collection stats, and a handful of performance and bug fixes.

API Improvements

Rate Limit Changes and Visibility

The API rate limit was adjusted to 20 requests/minute and 5,000 requests/day. To make this more transparent, the API now returns rate limit response headers on every response, so clients can see exactly how many requests they have remaining. Users can also see their current daily API usage — requests used, remaining, and a color-coded progress bar — directly in their profile's Account Settings section.

Conditional Request Support

Two more endpoints now support conditional requests (ETags / If-None-Match):

  • The reading list detail endpoint — item add/remove operations now bump the parent list's modified timestamp, so clients can detect item changes without polling /items/.
  • The /issue_list/ endpoints — thanks to Jonas Stendahl for this contribution.

This means clients can avoid re-downloading unchanged data, saving bandwidth for both users and the server.

Reading List Enhancements

The ReadingList model and API received several new additions:

  • list_type field — exposed in both the list and detail serializers, with human-readable display values.
  • image field — reading lists can now have a cover image. When set, the reading list detail page displays a semi-transparent hero header using the image; it falls back to the plain header when none is present.

Bug Fixes

  • Fixed a PATCH request to SeriesViewSet that was silently clearing the imprint field when it was omitted from the request body.
  • Fixed the ReadingList unique constraint to include attribution_source, allowing a user to have multiple lists with the same name as long as they come from different sources.

Reading List Web Views

  • Added a publisher filter to the reading list view, available in the Advanced Filters panel.
  • Fixed an issue count display bug in ReadingListListView.
  • Fixed a slow query in the publisher filter — the previous JOIN-based approach caused ~30 second response times on live data. We implemented a subquery-based approach is 5.6x faster.

Collection Stats

  • Added Top Writers and Top Artists horizontal bar charts to the Collection Stats view.
  • Fixed chart text readability in dark mode — chart tick labels, grid lines, legend text, and titles now follow Bulma's theme-aware colors rather than Chart.js's hardcoded defaults.

General UI / Frontend

  • Cover images in issue detail pages and card grids now handle landscape-oriented covers correctly. Instead of forcing all covers into a portrait 2by3 aspect ratio with a center crop, the template detects the aspect ratio of the generated thumbnail and uses is-3by2 for landscape images and is-2by3 for portrait.

Performance

  • Replaced prefetch_related with select_related in HomePageView for recently edited issues, reducing two extra queries to a single JOIN.
  • Eliminated unnecessary series type queries in several views — thanks to Jonas Stendahl for this contribution.
  • Fixed issue count annotations not appearing in PublisherSeriesList and ImprintSeriesList card grids.

Bug Fixes

  • Fixed an autocomplete widget crash (Internal Server Error) on create/update views when submitting a form without selecting an autocomplete field value. A SafeAutocompleteWidget subclass now normalises empty string and empty list values to None before the upstream widget tries to filter on them.

Dependency Updates

  • Updated to Django 5.2.12.
  • Updated Pillow.

Contributors

Thanks to Jonas Stendahl for his contributions this month.

Mokkari

Here's a summary of everything that landed in Mokkari during March, covering rate-limiting overhaul, new schema fields, and dependency refreshes.

Rate Limiting Changes

Reduced API limits

The per-session rate limits were updated to match the current Metron website limits:

LimitOldNew
Per minute3020
Per day10,0005,000

Pluggable rate-limit buckets

Session and the top-level api() function now accept an optional bucket parameter typed as AbstractBucket from pyrate_limiter. This lets you plug in any compatible backend — Redis, a database, or a plain in-memory store — to share rate-limit state across multiple workers or processes.

The default behaviour is unchanged: a SQLite-backed bucket is created lazily and shared across all sessions in the same process. A DEFAULT_RATES constant is now exported from mokkari.session so you can construct custom buckets with the same rate definitions:

from pyrate_limiter import RedisBucket
import redis
import mokkari

pool = redis.ConnectionPool.from_url("redis://localhost:6379")
bucket = RedisBucket.init(mokkari.session.DEFAULT_RATES, redis.Redis(connection_pool=pool), "mokkari")
m = mokkari.api("username", "password", bucket=bucket)

Contributors

Thanks to Myers Carpenter for his initial work on the pluggable rate-limit buckets this month.

Reading List Schema Additions

Two new fields were added to the reading list schemas:

  • image — an image URL field on ReadingListRead, surfacing the cover image for a reading list.
  • list_type — a new field on the reading list schemas that exposes the list's type classification.

Metron-Tagger

Here's a summary of everything that landed in Metron-Tagger during March, covering rate limit improvements, bug fixes, and dependency updates.

Rate Limit Handling

The tagger's handling of Metron API rate limits was improved:

  • Clock-skew buffer — A RATE_LIMIT_RETRY_BUFFER constant (2 seconds) is now added to every retry_after wait to account for small differences between the client clock and the server clock, reducing the chance of hitting the limit again immediately after waking up.
  • Nested rate limit handling — If a second rate limit error is encountered during a retry attempt, the tagger now performs one additional silent wait-and-retry instead of surfacing an error to the user. Only if that second retry also fails is an error reported.

These changes result in fewer spurious rate-limit errors when tagging large batches of comics (#238).

Bug Fixes

  • Fixed a crash that occurred when a MetronInfo file did not include an info_source field. Previously, iterating over md.info_source without checking for its existence would raise an exception. The fix adds an early None guard in get_id_from_metron_info so files without a source are silently skipped rather than crashing the tagger.

Dependency Updates

  • Updated the Mokkari dependency to pick up its latest improvements.

Contributors

Thanks to @bearinfo for his contributions this month.

Desaad

During March several new features around content discovery, reading list management, and library gap tracking were made.

Creator Views

Creators now have their own browsable pages. A new Creators section in the navigation gives access to a full creator list and individual detail pages showing a creator's roles across your library. A dedicated Creator Series/Issues view lets you drill down into their work by series.

Bookmarks

You can now bookmark series and issues directly from the list views. A bookmark icon overlays the cover image; clicking it toggles the bookmark state inline via HTMX without a page reload. A new Bookmarks page collects all your saved items in one place, with inline unbookmark support.

Advanced Search for Series and Issues

The Series and Issue list views gained advanced filtering capabilities. You can now filter by multiple criteria simultaneously, making it much easier to navigate large libraries.

Reading List Refresh with Conditional Requests

Reading lists sourced from Metron can now be refreshed. Desaad stores the modified datetime returned by Metron and uses it on subsequent refresh requests via If-Modified-Since. If Metron returns 304 Not Modified, you'll see an "already up to date" message. Otherwise, existing items are cleared and a background re-import is enqueued. A Refresh button appears on the detail page for any Metron-sourced list with a completed import.

Series Missing Issues Tracking

Desaad can now check your local library against Metron to identify issues in a series that you don't yet have. A new MissingSeriesIssue model tracks these gaps, and a Check Missing Issues button on the series detail page triggers the check inline via HTMX. Like reading list refresh, subsequent checks use conditional requests — if nothing has changed on Metron's side, you'll see an "already up to date" response.

Image of the missing issues on the Series Detail view

A dedicated Missing Issues list view provides an overview of all tracked gaps across your library, and a background task automatically cleans up missing issue records when you import a previously absent issue.

Reading List Improvements

Reading list search results and detail pages now show human-readable attribution source labels. Issue type display and filtering were added to reading list items, and attribution source tags appear on reading list cards for quicker at-a-glance identification.

Image of the reading list view

OpenCollective

A huge thank you to everyone who has contributed to our Open Collective! Your support makes a real difference in keeping the Metron Project running and growing.

What Your Contributions Support

Funds from Open Collective go directly toward:

  • Server hosting costs - Keeping the Metron website and API available
  • Domain registration - Annual domain name renewals
  • Future capacity increases - Scaling resources as the database and user base grows

All expenses are transparent and publicly viewable on our Open Collective page, so you can see exactly where every dollar goes.

Support the Project

If you'd like to help keep the lights on and support continued development, contributions of any size are appreciated and help ensure Metron remains a free resource for the comic book community.

Anyway, that's everything for this month! Take care.

API Rate Limit Reduction

· 2 min read
Brian Pepple
Founder of the Metron Project / Code Monkey

As mentioned in our February 2026 update, we have been dealing with increased server load due to the growth in API usage. We have made the decision to reduce the API rate limits effective immediately.

The new limits are:

  • 20 requests per minute (down from 30)
  • 5,000 requests per day (down from 10,000)

We know this is not ideal, and we're sorry for any inconvenience this may cause. If we receive enough donations in the future to cover the cost of a server upgrade, we would look at restoring the daily limit back to 10,000 requests per day.

Updated Client Libraries

New releases of our client libraries have been published that reflect these updated rate limits:

  • Mokkari v3.20.0 — the Python wrapper for the Metron API has been updated with the new rate limit configuration.
  • Metron-Tagger v4.9.0 — updated to use the latest version of Mokkari, picking up the new rate limits automatically.

If you use either of these tools, we recommend upgrading to the latest version.

Note for API Consumers

If you have written software that directly consumes the Metron API, please ensure your code correctly handles HTTP 429 (Too Many Requests) responses. When this status code is returned, the response will include a Retry-After header indicating how many seconds to wait before retrying. Your application should respect this header and delay its next request accordingly, rather than continuing to hammer the server. Failing to handle this gracefully may result in your requests being blocked.

If you have any questions or suggestions, don't hesitate to e-mail me or ping me on Matrix.

February 2026 News

· 6 min read
Brian Pepple
Founder of the Metron Project / Code Monkey

Monthly Statistics

During February the Metron Project added the following to its database:

  • Users: 152
  • Issues: 1,357
  • Creators: 246
  • Characters: 678

Thanks to everyone that contributed!

API Usage

Over the last 6 months, API usage has seen a significant increase — which is great! However, we are now at a point where our current server capacity is being strained.

Screenshot of a CPU load

Jonas Stendahl and I have landed some optimizations in the site's code, but they only go so far in relieving the pressure.

That leaves us with two options:

  1. Upgrade our server capacity — an additional $27–$43/month depending on the CPU tier selected.
  2. Reduce the daily rate-limit from 10,000 requests to something like 5,000.

Option #1 is clearly preferable, but we currently don't receive enough donations to cover the extra cost. That means we will likely need to reduce the daily rate-limit in the very near future, and we'll post an announcement here when that happens.

If you have other ideas or suggestions, please reach out!

Website Updates

Performance Improvements

Several changes were made to improve API and database query performance.

  • API query optimization: Refactored multiple API endpoint viewsets to reduce unnecessary database queries through better use of select_related and prefetch_related.
  • Additional database indexes: Added missing indexes on several models (Publisher, Series, Team, Universe) and their related issue querysets, which should speed up common lookups. (jyggen)
  • Fixed paginated Series queryset warning: Added explicit order_by() to SeriesViewSet and the publisher series-list action to resolve a UnorderedObjectListWarning that could surface during pagination.

API Enhancements

  • Conditional request support: The API now supports HTTP conditional requests using ETag and Last-Modified headers. Clients can send If-None-Match or If-Modified-Since headers to avoid re-downloading unchanged data, saving bandwidth. (jyggen)
  • Read dates in collection API: The collection list endpoint now includes read_dates data, giving API consumers access to reading history information directly from the list view.

Collection & Reading History

  • Reading history charts: The Collection Statistics page now includes daily (last 30 days) and monthly (last 12 months) column charts showing reading activity over time. Days with no reading activity are included in the daily chart.
  • Refined badge display logic: The read-count badge is now only shown when an issue has been read multiple times on the same calendar day, avoiding misleading counts from reads on different days.

User Interface Fixes

  • ESC key closes cover modal: On issue detail pages, pressing the Escape key now closes the cover image modal, matching standard UX conventions.
  • Variant formset display tweaks: Minor layout improvements to the variant issue formset to better display its fields.
  • User template improvements for editors: The user profile template now shows additional information for editors.
  • Series form validation fix: Handled a case where a missing series type would cause an unhandled error during form validation.

Other

  • Django 5.2.11 (#454): Updated to the latest Django 5.2 patch release.

Mokkari Updates

The following changes made to Mokkari, the Python wrapper for the Metron API, over the past month:

Added if_modified_since parameter to detail endpoints

All the detail methods (arc, character, creator, imprint, issue, publisher, series, team, universe, reading_list, and collection) now accept an optional if_modified_since datetime parameter. When provided, the request includes an If-Modified-Since HTTP header (formatted per RFC 7231) and returns None on a 304 Not Modified response — useful for efficiently detecting whether a resource has changed since you last fetched it. Naive datetimes are treated as UTC, and non-UTC datetimes are automatically converted before the header is sent.

Added Read Dates to CollectionList schema

The collection schemas have been updated to match the latest Metron API:

  • A new ReadDate model was added with id, read_date, and created_on fields.
  • read_dates and read_count fields were added to CollectionList and CollectionRead.
  • The date_read field type in CollectionRead was changed from date to datetime to align with the API's date-time format.

Migrated to PyrateLimiter 4.x

The rate-limiting implementation was updated for the breaking changes in pyrate-limiter 4.0:

  • Removed the now-deleted BucketFullException and LimiterDelayException imports.
  • Simplified Limiter construction.
  • Rewrote _check_rate_limit() to use the boolean return value of try_acquire(blocking=False) instead of catching exceptions.

Desaad Update

Here's a roundup of changes shipped to Desaad over the past month.

Reading History Import

The import_reading_status management command was upgraded: it now imports reading history dates from Metron, not just reading status. A new ReadDate model was added to store the actual date an issue was read, and the UserStatsView was updated to use these dates for reading activity stats. Previously, stats reflected the import timestamp rather than when issues were actually read.

Importer: Require External IDs

The comic importer was tightened up to require an external ID when creating characters, teams, universes, arcs, locations, genres, and creators. Previously, the importer would fall back to name-based lookups and create records without a verified external ID, leading to potential unverified duplicates. This change simplifies the importer significantly and ensures all entities can be reliably matched against a metadata source.

Reader UX: Double-Tap Confirmation

The comic reader's Prev Issue, Next Issue, and Close buttons now require a double-tap to activate. On the first tap, the button turns yellow and prompts "Tap again"; a second tap within 2 seconds proceeds with navigation. Otherwise, the button resets. This prevents accidental navigation away from your current reading position.

Infrastructure Updates

  • Python 3.14: The container image was updated to use Python 3.14.
  • Timezone via environment variable: The Django timezone setting is now configurable via an environment variable. Missing DB_* variables were also documented in the README.
  • Dependency updates: Project dependencies were refreshed across the board.

OpenCollective

A huge thank you to everyone who has contributed to our Open Collective! Your support makes a real difference in keeping the Metron Project running and growing.

What Your Contributions Support

Funds from Open Collective go directly toward:

  • Server hosting costs - Keeping the Metron website and API available
  • Domain registration - Annual domain name renewals
  • Future capacity increases - Scaling resources as the database and user base grows

All expenses are transparent and publicly viewable on our Open Collective page, so you can see exactly where every dollar goes.

Support the Project

If you'd like to help keep the lights on and support continued development, contributions of any size are appreciated and help ensure Metron remains a free resource for the comic book community.

Anyway, that's everything for this month! Take care.

January 2026 News

· 5 min read
Brian Pepple
Founder of the Metron Project / Code Monkey

Monthly Statistics

During January the Metron Project added the following to its database:

  • Users: 169
  • Issues: 2,238
  • Creators: 395
  • Characters: 1,430

Thanks to everyone that contributed!

Website Updates

New Features

Scrobble API Support

A new /scrobble endpoint allows users to quickly mark issues as read via the API with optional rating and timestamp. This enables integration with third-party reading apps and automated tracking workflows. The date_read field was migrated from a date to datetime for more precise tracking.

Reading History

Users can now view their reading history in a timeline layout with daily grouping. Recent reading activity also appears on user profile pages.

Multiple Read Dates

Collection items now support tracking multiple read dates, since comic issues are often re-read over time. The UI includes HTMX-powered controls for adding and removing read dates directly from the detail page.

Community View

User profiles now use username-based URLs (/accounts/username/) instead of numeric IDs. A new user list view with search functionality was added, making it easier to find and view other community members.

Improvements

HTMX Migration

Significant portions of the frontend JavaScript have been replaced with HTMX:

  • Global HTMX import in the base template
  • Navbar burger menu converted to HTMX
  • File upload handlers simplified with inline onchange attributes
  • Notification dismissals now use HTMX
  • Modal dialogs for read date deletion converted to HTMX
  • Removed several legacy JavaScript files (jquery.formset.js, bulma-modal.js, bulma-navbar-burger.js, bulma-notifications.js)

Auto-Dismissing Notifications

Non-error notifications now automatically disappear after 5 seconds. Error messages remain visible until manually dismissed.

Issue Autocomplete Search

The issue autocomplete now supports more flexible searching:

  • Search terms can be in any order ("Spider Amazing" matches "Amazing Spider-Man")
  • Series year filtering using parentheses (e.g., "Speed Racer (2025) #4")

Email Compatibility for Account Activation

Updated how Metron sends account activation emails to ensure they display correctly across all major email clients.

The changes include:

  • Multipart emails: Activation emails now send both HTML and plain text versions, ensuring users can read them regardless of their email client settings
  • Universal styling: Replaced CSS stylesheets with inline styles, since Gmail and Outlook strip CSS from the <head> section
  • Table-based layout: Switched from div-based layouts to tables for consistent rendering in older email clients
  • Better color support: Removed CSS gradients in favor of solid colors for Outlook compatibility
  • Web-safe fonts: Now using Arial and Helvetica instead of system fonts for cross-platform consistency

These updates should ensure new users have a smooth onboarding experience, regardless of whether they use Gmail, Outlook, Apple Mail, or any other email client.

Bug Fixes

  • Fixed duplicate issue creation race condition—users now see a friendly error instead of a 500 error
  • Fixed SlugRedirectView when requesting non-existent items
  • Fixed success message formatting in user account activation
  • Fixed sequential read date deletion (HTMX event handlers now reinitialize properly after content swaps)

Infrastructure

  • Updated to Django 5.2.10
  • Removed request for GitHub stars from the welcome flow

Desaad Updates

The following changes were made to Desaad.

Scrobbling to Metron

Issue scrobbling was added this month, and more information on it can be found in this blog post.

Database Migration to PostgreSQL

The application has migrated from SQLite to PostgreSQL. This followed an initial attempt to improve SQLite concurrency with WAL mode and retry logic, but PostgreSQL proved to be a better fit for handling concurrent operations during comic imports while the web server is running.

Reader Improvements

The comic reader received several updates:

  • Added previous/next issue navigation for reading through a series
  • Added gesture hints overlay to help users discover touch controls
  • Implemented browser caching for page images with proper HTTP cache headers (ETag, Cache-Control)
  • Improved performance by using the stored page count from the database rather than reading from the archive each time
  • Added customizable auto-hide delay for reader controls

After testing both approaches, the reader reverted to using base64 image data instead of image URLs, as this provided a better reading experience.

Background Task Processing

The app now uses Django 6.0's Tasks framework with django-tasks[rq] for several operations:

  • Reading list imports now run asynchronously with status polling via HTMX
  • Cover extraction is deferred to a background queue, making initial imports faster
  • Missing reading list items are automatically linked when matching issues are imported

Metron Integration

A new import_reading_status management command allows users to sync their reading history from their Metron collection. This imports completion status and ratings for issues that match by Metron ID. Currently, it only imports the read status, but in the near future it will add the dates the issues were read on also.

HTMX Adoption

Replaced JavaScript with HTMX in several places:

  • Notification dismiss buttons
  • Reading list detail page (delete modal, hide/show missing toggle)
  • Navbar burger menu

Other Changes

  • Added sorl-thumbnail with Redis cache backend for cover images
  • Added cover images to the series list view
  • Added a home view showing next unread issues for started series
  • Added completion indicators to reading list overview
  • Added django-debug-toolbar for development
  • Various container and deployment fixes

OpenCollective

A huge thank you to everyone who has contributed to our Open Collective! Your support makes a real difference in keeping the Metron Project running and growing.

What Your Contributions Support

Funds from Open Collective go directly toward:

  • Server hosting costs - Keeping the Metron website and API available
  • Domain registration - Annual domain name renewals
  • Future capacity increases - Scaling resources as the database and user base grows

All expenses are transparent and publicly viewable on our Open Collective page, so you can see exactly where every dollar goes.

Support the Project

If you'd like to help keep the lights on and support continued development, contributions of any size are appreciated and help ensure Metron remains a free resource for the comic book community.

Anyway, that's everything for this month! Take care.

Collection Scrobbling

· 3 min read
Brian Pepple
Founder of the Metron Project / Code Monkey

Introducing Collection Scrobbling

We've added a new scrobble endpoint to Metron that makes tracking your comic reading progress more convenient.

What is Scrobbling?

Scrobbling is a quick way to mark an issue as read via the API. The term comes from music services like Last.fm, where it refers to automatically tracking what you're listening to. For Metron, it means you can instantly log that you've finished reading a comic issue without navigating through the web interface.

How It Works

The new /api/collection/scrobble/ endpoint accepts a simple POST request with an issue ID. When you scrobble an issue, Metron will:

  • Mark the issue as read in your collection
  • Record the exact date and time you finished it
  • Optionally save a star rating (1-5)
  • Automatically add the issue to your collection if it's not already there

If the issue doesn't exist in your collection yet, scrobbling creates a new collection item with reasonable defaults (digital format, quantity of 1). If it's already in your collection, the endpoint just updates the read status and timestamp.

Why We Built This

The web interface works fine for managing your collection, but marking issues as read can feel cumbersome when you're actively reading. You have to navigate to the right page, find the issue, click edit, check the box, and save. That's several steps just to record something simple.

Scrobbling reduces this to a single API call. This opens up possibilities for:

  • Browser extensions that add a "mark as read" button to digital comic readers
  • Mobile apps that track reading activity in the background
  • Import scripts that bring in reading history from other services
  • Reading tracker tools that focus specifically on logging your progress. If you are using Dessad this feature has already been added.

Technical Changes

To support more precise tracking, we migrated the date_read field from DateField to DateTimeField. This means you can now track exactly when you finished reading an issue, not just which day. All existing data was preserved during the migration.

Reading History

Along with scrobbling, we added a reading history view that displays your recently-read comics in a timeline format. You can see:

  • When you read each issue (with exact timestamps)
  • Cover thumbnails for quick visual reference
  • Format badges showing whether you read print or digital
  • Your star ratings

The full reading history is available at /collection/history/, and your user profile now shows your 10 most recent reads.

Getting Started

To scrobble an issue, make a POST request to /api/collection/scrobble/:

{
"issue_id": 12345,
"date_read": "2026-01-08T14:30:00Z",
"rating": 4
}

The date_read and rating fields are optional. If you omit date_read, it defaults to the current timestamp.

Authentication is required (Basic Auth or session), and the endpoint respects collection privacy—you can only scrobble to your own collection.

What's Next

The scrobble endpoint provides a foundation for better reading tracking. We'd like to see what tools the community builds with it. If you create a browser extension, mobile app, or other integration, let us know.

For complete API documentation, see the User Collection Documentation.

December 2025 News

· 9 min read
Brian Pepple
Founder of the Metron Project / Code Monkey

Monthly Statistics

During December the Metron Project added the following to its database:

  • Users: 99
  • Issues: 1,668
  • Creators: 208
  • Characters: 1,176

Thanks to everyone that contributed!

Website Development

🎉 New Feature: User Collections

This month I added a User Collections system that lets you track your personal comic book collection. You can manage your collection by adding or removing issues, mark things as read, and track comic condition using the CGC grading scale (0.5 to 10.0). The grading system supports professional grading companies like CGC, CBCS, and PGX, as well as user-assessed grades for raw comics.

There's also a star rating system (1-5 stars) for rating issues in your collection, format tracking for print and digital copies, and bulk operations to add entire series runs at once. If you're trying to complete runs, there's a missing issues tracker that shows you which issues you need and displays completion percentages for each series.

The feature includes collection statistics with visual charts, advanced filtering options to search by series, publisher, format, read status, grade, and more. There are also read-only API endpoints for accessing your collection data and statistics, along with documentation to help you get started.

📚 Reading Lists Enhancements

Reading lists got some updates this month. You can now tag issues as Prologue, Core Issue, Tie-In, or Epilogue, with inline editing and visual badges to make it easier to see what's what. I also added a 5-star rating system for public reading lists, so you can see average ratings and filter lists by minimum rating.

There's also story arc integration that lets you add all issues from a story arc to a reading list in one go, which should save some time. I created a "reading list editor" group for managing Metron's curated lists - this allows trusted users to help curate without needing full staff privileges. If you're interested in being part of this group, just let me know.

The reading list API now supports browsing and retrieving lists with paginated results (50 items per page) and filtering options.

🔍 Search & Filtering Overhaul

I spent some time improving the search functionality across the site. Series lists now support multi-word search with filters for type, publisher, imprint, year range, status, and volume. Issue lists have quick search with advanced filters for series info, dates, and IDs. Reading lists can be searched by name, creator, attribution source, and privacy status. User collections have quick search across series names and notes with multi-field filtering.

All the search interfaces now have collapsible advanced filter sections, preserve your filter state, show active filter indicators, and have better empty states. I tried to keep the UI patterns consistent across all of them.

🐛 Bug Fixes

Week Views Date Calculation Fix (#437)

Fixed a bug where WeekList, NextWeekList, and FutureList views were using class-level date calculations evaluated at import time. This meant the views would always show the same week (from when the server started) instead of updating dynamically. I moved the date calculations to per-request methods and switched to precise date range queries to fix this.

📱 Mobile Improvements

Fixed a few mobile-specific issues this month: filter buttons now work properly on mobile devices, improved the home page responsiveness, fixed layout issues in home.html, and cleaned up button layouts across collection and reading list views.

🎨 UI/UX Enhancements

Added a Reading List & Collections section to the home page, made the first information card full width, and improved the overall layout for better visual hierarchy. I also spent time optimizing database queries - reading list detail views went from around 20 queries down to 4-6 by using better prefetching and annotation strategies. Collection detail views now show cover images and descriptions with lazy loading.

🔒 Security & Validation

Improved permission checks across reading list operations.

🔧 Technical Improvements

Upgraded to Django 5.2.9 and added documentation for User Collections and Reading Lists, including user guides, technical documentation for developers, and API documentation. I also refactored and simplified some views with better inheritance patterns.

Looking Ahead

Now that User Collections is up and running and Reading Lists have been improved, the plan is to refine these features based on user feedback and explore additional integration opportunities.

Desaad: A Comic Book Library Management System

What is Desaad?

Desaad is a self-hosted, web-based comic book library manager and reader built with Django that I've been working on over the past week or so. I created it to test and plan features for Metron that might be useful for other comic servers.

Key Features

Library Management

Desaad imports CBZ, CBR, and PDF comic archives and automatically pulls metadata from MetronInfo.xml files - things like series information, publishers, creators, characters, teams, universes, and story arcs. I'm not planning to add ComicInfo.xml support, since there are a lot of comic servers that already do.

It uses Darkseid for handling comic archives and extracting metadata.

Screenshot of a Series Detail Screenshot of a Issue Detail

Built-in Web Reader

The web reader uses HTMX and automatically saves your reading position and progress, so you can pick up where you left off.

Reading Lists

You can import reading lists from Metron using the API. The feature automatically tracks which issues are in your library and shows you which ones you're missing.

Screenshot of a Reading List
OPDS 1.2 Catalog Support

You can access your comic library from mobile devices and e-readers using OPDS-compatible apps like Chunky Comic Reader (iOS), Panels (iOS), or Challenger Comics Viewer (Android).

I tried testing it with the Challenger app, but their OPDS support doesn't seem to work and is still marked as Beta. If anyone wants to test with Chunky or Panels, I'd appreciate hearing how it goes.

Auto-Import Functionality

There's an import management command that you can run manually or set up to watch a directory for new comics.

I haven't optimized it much yet - the most expensive part is cover extraction, which I'll probably move to a background task at some point. I deployed it on a spare GMKtec NucBox G3 I had, and it took about 3 hours to import around 65,000 comics. Once I move cover extraction to a background task, I should be able to get that down to 1-2 hours.

Technical Foundation

Desaad is built on Django 6.0 with SQLite for simplicity (though I'll probably switch to PostgreSQL at some point since SQLite has some performance limitations and missing features). The frontend uses the Bulma CSS framework with HTMX, and comic processing is handled by the Darkseid library. It's container-ready with Podman support and systemd integration.

It requires Python 3.13+ and uses the uv package manager for dependency management.

Important Considerations

A few things to keep in mind about Desaad:

  1. Single Metadata Source: It assumes all your comics use metadata from a single source (Metron, Comic Vine, etc.). Mixed metadata sources aren't supported.

  2. MetronInfo.xml Format: Only supports the MetronInfo.xml metadata specification. Your comics need metadata written by software that implements this spec.

  3. Under Active Development: The project is still under construction and not ready for production use. Features and APIs will change.

Who Should Use Desaad?

Desaad might be a good fit if you're a developer or tester who prefers browser-based reading and wants to see possible new features like scrobbling. It works best if your collection uses metadata from a single source (Metron, Comic Vine, or Grand Comics Database). If your collection has mixed metadata from multiple sources, Desaad probably isn't the right tool for you.

Getting Started

Setting up Desaad is pretty straightforward:

# Clone the repository
git clone https://codeberg.org/bpepple/desaad.git
cd desaad

# Configure environment
cp .env.example .env
# Edit .env with your settings

# Install dependencies and setup
uv sync
uv run python manage.py migrate
uv run python manage.py createsuperuser
uv run python manage.py collectstatic

# Run the development server
uv run python manage.py runserver

For production deployments, there are Podman compose configurations with systemd service integration.

Container Deployment

If you're using Fedora Linux, the included Podman configuration should make deployment simple. It should work on other systems running Podman too, but I haven't tested that yet. To get started:

# Build and start
podman-compose up -d

# Create admin user
podman-compose exec web python manage.py createsuperuser

# Import comics
podman-compose exec web python manage.py import_comics

The application will be available at http://localhost:9000.

There's more information in the project's README.md, including how to create systemd service files.

OpenCollective

A huge thank you to everyone who has contributed to our Open Collective! Your support makes a real difference in keeping the Metron Project running and growing.

What Your Contributions Support

Funds from Open Collective go directly toward:

  • Server hosting costs - Keeping the Metron website and API available
  • Domain registration - Annual domain name renewals
  • Future capacity increases - Scaling resources as the database and user base grows

All expenses are transparent and publicly viewable on our Open Collective page, so you can see exactly where every dollar goes.

Support the Project

If you'd like to help keep the lights on and support continued development, contributions of any size are appreciated and help ensure Metron remains a free resource for the comic book community.

Anyway, that's everything for this month! Take care.

User Collections

· 4 min read
Brian Pepple
Founder of the Metron Project / Code Monkey

I've spent the last week or so, implementing User Collections, a feature for Metron that lets you catalog, organize, and track your personal comic book collection.

What is User Collections?

User Collections is a comic book collection management system.

Key Features

📚 Complete Cataloging

Track every aspect of your collection:

  • Quantity tracking for duplicate copies
  • Format support (Print, Digital, or Both)
  • Professional grading (CGC, CBCS, PGX) or self-assessed grades
  • Purchase details including date, price, and store
  • Storage locations to help you find your comics
  • Personal notes for each item

⚡ Bulk Operations

Adding your entire collection is fast and efficient:

  • Add entire series runs in seconds with the "Add from Series" feature
  • Specify issue ranges to add specific portions of a series
  • Automatic duplicate detection prevents adding the same issue twice
  • Smart defaults for format and reading status when adding multiple issues

📊 Statistics & Analytics

Get insights into your collection:

  • Total items and value tracking
  • Reading progress (read vs. unread counts)
  • Format breakdown with visual charts
  • Publisher distribution to see where your collection focuses
  • Top 10 series by item count
  • Series type analysis (ongoing, mini-series, etc.)

🔍 Smart Gap Detection

Helps you complete your series runs:

  • Missing Issues list shows series where you own some but not all issues
  • Color-coded progress bars (red/yellow/green) indicate completion percentage
  • Detailed missing issue views list exactly which issues you need
  • Completion statistics help you prioritize which series to finish

⭐ Reading Tracker & Ratings

Track your reading journey:

  • Mark issues as read with date tracking
  • 5-star rating system for personal recommendations
  • Quick rating via HTMX (no page reload required)
  • Filter by reading status to find unread comics

🔐 Privacy First

Your collection is completely private:

  • Login required for all collection features
  • No public sharing (unlike reading lists)
  • Owner-only access ensures only you can view/edit your items

How It Works

Adding Individual Issues

Navigate to /collection/add/ and search for any issue using the autocomplete feature. Fill in optional details like grade, purchase price, storage location, and click "Add to Collection."

Bulk Adding from Series

Visit /collection/add-from-series/ to quickly add entire series runs:

  1. Select a series
  2. Choose to add all issues or specify a range (e.g., #1-50)
  3. Set default format and reading status
  4. Click "Add Issues"

The system automatically skips issues already in your collection, making it perfect for cataloging longboxes or digital libraries.

Finding Missing Issues

The Missing Issues feature (/collection/missing/) identifies gaps in your series runs:

  • See completion percentages for each series
  • Click "View Missing" to see specific issue numbers
  • Use these lists when shopping for back issues
  • Track your progress toward completing series

Powerful Filtering

Find exactly what you're looking for with extensive filtering options:

  • Series name, publisher, or imprint
  • Grade and grading company
  • Format (print/digital/both)
  • Reading status and ratings
  • Storage location or purchase store
  • Combine multiple filters for precise searches

Technical Highlights

Built on Django with:

  • CGC grading scale with 27 grade levels (0.5 to 10.0)
  • Money field support for accurate purchase price tracking
  • HTMX integration for seamless rating updates
  • Chartkick visualizations for statistics
  • Optimized queries with proper indexes for performance
  • Unique constraints prevent duplicate entries
  • RESTful API available at /api/collection/

Use Cases

For Completionists: Use Missing Issues to systematically fill gaps in your series runs. Color-coded progress bars show which series you're close to completing.

For Investors: Track purchase prices and grades for valuable books. Monitor total collection value and maintain detailed records for insurance.

For Readers: Mark issues as read, rate them, and track your progress. Filter to find unread comics in your collection.

For Organizers: Use storage locations to keep track of where comics are physically stored. Perfect for managing multiple longboxes or storage units.

Mokkari

A new release of Mokkari will be made this week with support for the user collections API endpoints.

Possible Future Enhancements

More Import Options: When I get some time, I'll look at adding support for importing existing collections. If you track your collection elsewhere I'd be interest what export options you have, so please contact me.

Wish List: A logical addition would be to have the option for make a wish list of issues to purchase.

Pull List: Another closely related feature that could be useful.

Comic Value: It would be interesting to be able to provided estimated market values for issues.

November 2025 News

· 5 min read
Brian Pepple
Founder of the Metron Project / Code Monkey

Monthly Statistics

During November the Metron Project added the following to its database:

  • Users: 30
  • Issues: 1,042
  • Creators: 158
  • Characters: 531

Thanks to everyone that contributed!

Reading Lists

Mea Culpa

So... the last post I made introducing Reading List, unfortunately caused a bit of drama, since I forgot to attribute that the 13 initial reading lists were created from cbl files from the CBL-ReadingLists group. I'm sorry for this oversight and it wasn't my intention to give the impression they were created by me. I've since made a note on those reading lists attributing them to this group, and removed the import CLB functionality from the site.

Due to the aforementioned drama, I've had to call a bit of an audible in regard to the maintaining of the reading lists owned by the Metron user. I'm planning to work on adding support for non-admin users to edit these lists over the Holiday break and if you have an interest in helping to maintain them, please contact me.

One side-effect of my mistake is that it spurred on one of our community members to write a tool to retrieve the data directly from the reading lists source and check them against the site, and then produce a json file or if issues are missing generate a report that can be acted upon. Currently, I've got a management command to import these json files, but maybe I'll look at adding POST support to the API in the future.

Down the road, I'll look at adding arc-based bulk additions, other import options, and maybe an associated reading list fields.

Adding Series to Reading List

I've added the option to add a series to a reading list, which should be easier than just adding individual issues.

API

I've spent the last week or so working on the Reading List API, and it's finally been pushed to production. There is fairly detailed API documentation on the wiki, and there is also the Swagger API Documents.

I was originally planning to write a simple tool to generate reading lists from the API, but have held off due to:

  • CBL files don't really have a schema.
  • json-cbl-standard aren't currently designed to handle information from an API that well.

Mokkari

A new version of Mokkari has been released that adds support for the new Reading List API, and also reworked the rate limiting code so that it produces more feedback to the user. If you have written an application that uses Mokkari, you'll want to modify your API calls to Metron to sleep when receiving RateLimitError. For example:


>>> import time
>>> from mokkari.exceptions import RateLimitError
>>> session = Session("username", "password")
>>> def fetch_with_rate_limit_handling(issue_id):
... while True:
... try:
... return session.issue(issue_id)
... except RateLimitError as e:
... if "per minute" in str(e):
... # Minute limit - automatically wait and retry
... print(f"{e}")
... print(f"Waiting {format_time(e.retry_after)}...")
... time.sleep(e.retry_after)
... continue
... elif "per day" in str(e):
... # Daily limit - ask user whether to wait or quit
... response = input(f"Wait {format_time(e.retry_after)}? (y/n): ")
... if response.lower() == 'y':
... time.sleep(e.retry_after)
... continue
... else:
... raise
... else:
... raise
>>> issue = fetch_with_rate_limit_handling(1)

Metron-Tagger

A couple of releases of Metron-Tagger were made since my last blog post. The big change was support for writing/reading metadata was added, but implemented differently than other tagging software which have overloaded the PDF metadata. I decided to treat PDFs, like we do with CBZ, by embedding the metadata.

After discussing this with AJ, he has also made a release of Comicbox supporting this method of writing comic metadata to a PDF.

The latest release has also improved the rate limiting, so that when the daily limit is exceeded, the user is asked whether they want to wait the reported number of minutes or quit processing the remaining files.

Cloudflare

The site has been dealing with AiBots and scrapers quite a bit lately, and I'm giving serious thought to moving the site DNS over to Cloudflare to take advantage of the bot protection. I'm still working on what the migration plan would entail (name server changes, SSL certs, nginx, etc) and will make a decision once that's finished. If we do make the switch, the site will most likely be down for a while (assuming everything goes as planned), and I will put a notice on the site beforehand.

OpenCollective

If you would like to help keep the lights on at the project, we have an account at Open Collective to defray the servers costs and help with increasing future server capacity.

Anyway, I think that's everything for this month! Take care.

Reading Lists

· 6 min read
Brian Pepple
Founder of the Metron Project / Code Monkey

I'm happy to announce a new feature to the site that has been requested for awhile: Reading Lists.

What Are Reading Lists?

Reading Lists allow you to create curated, ordered collections of comic book issues. Think of them as your personal reading guides that you can build, customize, and share with the community.

Key Features

🎯 Create Custom Reading Orders

Build reading lists from scratch by searching through Metron's comic database. Our smart search makes it easy to find exactly the issues you need (provided it exists in the database):

  • Search by series name and issue number
  • Use the # separator for precise searches (e.g., "Amazing Spider-Man #700")
  • Add multiple issues at once
  • Drag and drop to reorder issues exactly how you want them

🔒 Public or Private Lists

Share your research with the community by making your lists public, or keep them private for personal reference. It's your choice!

  • Public Lists: Help other readers discover great reading orders
  • Private Lists: Perfect for tracking your personal reading queue

📚 Smart Organization

Every reading list automatically displays helpful information:

  • Date Range: See the start and end years covered by the list
  • Publishers: View all publishers represented in the reading order
  • Issue Count: Know exactly how many issues you're committing to

🔍 Easy Discovery

Find the perfect reading order with our search functionality:

  • Search by list name (e.g., "Civil War")
  • Search by creator/username
  • Filter by attribution source
  • Browse all public lists

📥 CBL Import (Admin Feature)

For site administrators, we've included support for importing Comic Book List (.cbl) files from popular reading order websites. This means we can quickly add curated reading orders from trusted sources like:

  • Comic Book Reading Orders (CBRO)
  • Complete Marvel Reading Orders (CMRO)
  • Comic Book Herald
  • And many others!

Curated Reading Lists Coming Soon

We'll be importing a collection of curated reading lists from trusted sources in the near future! These researched reading orders will be available under the Metron user account for the entire community to enjoy.

What to expect:

  • High-quality reading orders from established comic reading order websites
  • Major crossover events and story arcs
  • Character-specific reading guides
  • Publisher-specific chronologies
  • All properly attributed to their original sources

These curated lists will complement the community-created lists and provide excellent starting points for readers looking to dive into complex storylines or explore new series.

Use Cases

Here are just a few ways you can use Reading Lists:

For Event Readers

Create comprehensive reading orders for major crossover events:

  • "Secret Wars (2015) - Complete Reading Order"
  • "DC's Crisis on Infinite Earths"
  • "Infinity Gauntlet and Tie-ins"

For Character Fans

Track a character's appearances across multiple series:

  • "Wolverine's First Appearances"
  • "Spider-Gwen Complete Chronology"
  • "The Many Robins of Gotham"

For New Readers

Help newcomers find the perfect entry point:

  • "Getting Started with the X-Men"
  • "Best Batman Stories for New Readers"
  • "Modern Marvel Essentials"

For Completionists

Organize entire eras or creative runs:

  • "Claremont's X-Men Run"
  • "Hickman's Marvel Universe"
  • "Grant Morrison's DC Work"

Getting Started

Ready to create your first reading list? Here's how:

  1. Log in to your Metron account
  2. Navigate to Reading Lists in the menu
  3. Click "Create Reading List"
  4. Give your list a name and description
  5. Choose public or private
  6. Click "Create"

Once created, you can start adding issues:

  1. Click "Add Issues" on your reading list
  2. Search for issues using the autocomplete field
  3. Drag and drop to reorder
  4. Click "Submit" to save

Search Tips

Our autocomplete search makes finding issues quick and easy:

Basic Search:

  • Type "spider" to find all Spider-Man related series

Smart Search with #:

  • Type "amazing #700" to find Amazing Spider-Man #700
  • Type "batman #1" to find Batman issue #1
  • Type "#100" to find all issue #100s

Pro Tip: The search works on both series names and issue numbers, so you can be as specific or as broad as you need!

Community Sharing

One of the most exciting aspects of Reading Lists is the ability to share your research with the community. If you've spent hours researching the perfect reading order for a complex storyline, make it public and help other readers benefit from your work!

When creating public lists, consider:

  • Using clear, descriptive names
  • Adding detailed descriptions explaining what the list covers
  • Organizing issues in the optimal reading order
  • Keeping the list updated as new issues are released

Attribution and Sources

We believe in giving credit where it's due. When creating a reading list based on someone else's research, please mention the source in your description. Admin users can also set official attribution sources and URLs when importing reading lists.

Examples to Inspire You

Here are some reading list ideas to get you started:

Event-Based Lists

  • "Avengers vs. X-Men - Complete Reading Order"
  • "Blackest Night - Full Crossover"
  • "House of M and Decimation"

Character-Focused Lists

  • "Miles Morales: Complete Journey"
  • "Harley Quinn: From Villain to Hero"
  • "The Death and Return of Superman"

Creator Runs

  • "Brian K. Vaughan's Runaways"
  • "Ed Brubaker's Captain America"
  • "Gail Simone's Birds of Prey"

Beginner Guides

  • "Start Here: Modern Marvel"
  • "DC Comics for New Readers"
  • "Essential Image Comics"

Thematic Lists

  • "Best Time Travel Stories"
  • "Multiverse Madness"
  • "Street-Level Heroes"

What's Next?

This is just the first part of the features for Reading Lists! I'm already planning on some future enhancements:

  • Provide API to search and retrieve Reading Lists data.
  • List statistics and analytics
  • Progress tracking (mark issues as read)

Join the Conversation

We'd love to hear your feedback! What reading lists are you excited to create? What features would you like to see added? Let us know in the comments or reach out to the Metron team.

Start Building Today

Reading Lists is live now! Log in to your Metron account and start creating your first reading list. Whether you're organizing your next reading marathon, helping new readers find their footing, or sharing your expertise with the community, Reading Lists makes it easy.

Ready to get started?

Happy reading, and we can't wait to see what amazing reading lists you create!