Skip to main content

A Python library for browser-based manual image classification

Project description

Classto

Classto is a Python library for building lightweight, browser-based tools to manually classify images into custom categories - ideal for preparing datasets or sorting visual content.

With just a few lines of Python, Classto spins up a local web interface built on Flask and styled with Tailwind CSS to let you quickly review, label, and organize images - right from your browser.

Interface Previews

Classto Light Mode     Classto Dark Mode

Classto in Light and Dark Mode

 

Features

  • Three Operational Modes: Local Folder, Static URL, or Dynamic Database Hooks.
  • One-Click Classification: Fast, keyboard-friendly browser UI.
  • Flexible Data Management: Moves local files, logs to CSV, or streams directly from cloud/DB pipelines.
  • Smart Suffixing: Optionally add unique filename suffixes to avoid naming conflicts.
  • Dark Mode Toggle: Easy on the eyes during long labeling sessions.

Installation

You can install Classto via pip:

pip install classto

Quickstart

Classto adapts to your workflow. You can use it in exactly one of the following three modes at a time:

1. Local Folder Mode

Reads images from a local directory, moves them into per-label subfolders, and optionally creates a CSV log.

import classto as ct

labeler = ct.ImageLabeler(
    classes=["Cat", "Dog"],
    image_folder="images",     # Mandatory path to your images
    delete_button=True,        # Shows a button to delete/skip images
    suffix=True,               # Add unique suffix to avoid conflicts
    log_to_csv=True            # Saves results to a local CSV file
)

labeler.launch()

Then open your browser at http://127.0.0.1:5000.

Local Folder Architecture

Place your images in a folder (e.g. images/) relative to your script:

project/
├── images/
│   ├── cat1.jpg
│   ├── cat2.jpg
│   ├── dog1.jpg
│   └── dog2.jpg
├── app.py

After classification, images are moved to:

project/
├── classified/
│   ├── Cat/
│   │   ├── cat1__K8dLs.jpg
│   │   └── cat2__a7JkL.jpg
│   ├── Dog/
│   │   ├── dog1__Xy4Tz.jpg
│   │   └── dog2__Zx9Pm.jpg
│   └── labels-20260522-163400Z.csv

2. Static URL Mode

Streams images directly from a list of web URLs. Classifications are tracked via a local CSV file.

import classto as ct

urls = [
    "https://example.com/image1.jpg",
    "https://example.com/image2.png"
]

labeler = ct.ImageLabeler(
    classes=["Product", "Background Only"],
    urls=urls,                     # Mandatory for URL Mode
    log_to_csv=True,               # Keeps track of URLs in a CSV file
    shuffle=True
)

labeler.launch()

3. Dynamic Hook Mode (Database Integration)

Integrate seamlessly with databases (e.g., MongoDB, Cosmos DB) or cloud storages. Images are streamed on-demand via custom callback hooks without loading datasets into memory or enforcing local file moves.

import classto as ct

# Define your custom database connection logic
def my_next_hook():
    # Fetch next document from DB. Must return {"id": str, "url": str} or None
    doc = db.images.find_one({"labeled": False})
    return {"id": str(doc["_id"]), "url": doc["image_url"]} if doc else None

def my_label_hook(image_id, label):
    # Save the label back to your database
    db.images.update_one({"_id": ObjectId(image_id)}, {"$set": {"label": label, "labeled": True}})

def my_stats_hook():
    # Update live session progress badges in the UI
    return {
        "total_remaining": db.images.count_documents({"labeled": False}),
        "total_labeled": db.images.count_documents({"labeled": True})
    }

def my_delete_hook(image_id):
    # Optional: Action when the delete/skip button is pressed
    db.images.update_one({"_id": ObjectId(image_id)}, {"$set": {"is_deleted": True, "labeled": True}})

labeler = ct.ImageLabeler(
    classes=["Valid", "Corrupted"],
    delete_button=True,
    on_next=my_next_hook,           # Mandatory for Hook Mode
    on_label=my_label_hook,         # Mandatory for Hook Mode
    on_get_stats=my_stats_hook,     # Optional: Renders live stats UI badges
    on_delete=my_delete_hook,       # Mandatory if delete_button=True in Hook Mode
    log_to_csv=False                # Optional: Set to True for a parallel local CSV backup
)

labeler.launch()

Parameters

  • classes (List[str]): A list of categories for classification (e.g. ["Dog", "Cat"]).
  • image_folder (Optional[str]): Path to the folder containing local images. Required for Folder Mode. Defaults to None.
  • urls (Optional[List[str]]): A list of image URLs to stream. Required for URL Mode. Defaults to None.
  • delete_button (bool): If True, shows a delete button to remove or skip images. Defaults to False.
  • shuffle (bool): If True, images are presented in a random order (applies to Folder and URL mode only). Defaults to False.
  • suffix (bool): If True, appends a random 5-character suffix to local filenames to prevent overwriting. Defaults to False.
  • log_to_csv (bool): If True, logs classifications into a local CSV file. Works as a primary tracker for URL mode or as a secondary backup across all modes. Defaults to False.
  • log_path (Optional[str]): Custom directory path where the CSV log file should be written.
  • log_file_name (Optional[str]): Custom file name for the CSV log. If omitted, a UTC-timestamped name is automatically generated.
  • on_next (Optional[Callable]): Hook returning {"id": str, "url": str} or None. Required for Hook Mode.
  • on_label (Optional[Callable]): Hook accepting (image_id: str, label: str). Required for Hook Mode.
  • on_get_stats (Optional[Callable]): Hook returning {"total_remaining": int, "total_labeled": int} to power the UI counter.
  • on_delete (Optional[Callable]): Hook accepting (image_id: str). Required if delete_button=True in Hook Mode.

CSV Logging Format

If log_to_csv=True is enabled, data is written into a CSV file containing the following structure:

original_filename new_filename label timestamp
img01.jpg img01__4Fg7T.jpg Cat 2026-05-22T16:34:00+00:00
img02.jpg img02__8Hv2f.jpg Dog 2026-05-22T16:34:32+00:00
  • original_filename: The local filename (Folder Mode) or the custom database image_id (Hook Mode).
  • new_filename: The new name after suffixing (Folder Mode) or the streamed image_url (Hook Mode/URL Mode).
  • label: The category selected during classification (or DELETED).
  • timestamp: Execution time in ISO 8601 format (UTC).

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

classto-2.1.0.tar.gz (477.3 kB view details)

Uploaded Source

Built Distribution

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

classto-2.1.0-py3-none-any.whl (473.6 kB view details)

Uploaded Python 3

File details

Details for the file classto-2.1.0.tar.gz.

File metadata

  • Download URL: classto-2.1.0.tar.gz
  • Upload date:
  • Size: 477.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for classto-2.1.0.tar.gz
Algorithm Hash digest
SHA256 33b4aea9b72e8bd5484c1edc80e49a8e2b0e35a14e63c5bddcc5658408409f6e
MD5 af8658ecf5e89bd62a3a9d0e203735e0
BLAKE2b-256 e6797ce0efe6c9e43c2552acf0017865419204cdba776a71f4a91c55d15979c6

See more details on using hashes here.

File details

Details for the file classto-2.1.0-py3-none-any.whl.

File metadata

  • Download URL: classto-2.1.0-py3-none-any.whl
  • Upload date:
  • Size: 473.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for classto-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5fd492243b519a0140bc62fffcc231a77a3fa5303c13289efdbec74598c9d26b
MD5 57aaba2b35194851c5ea1ded1fae801f
BLAKE2b-256 1d8c16a8d9f034bb3f7651d3d51e2e0dc3b3ca10bfcf8a705e33119e94f6837b

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