pyofsDB (0.1.0)

Published 2026-09-01 03:38:57 +00:00 by jakan

Installation

pip install --index-url  pyofsDB

About this package

Read-only access to the SQLite databases produced by OF-Scraper

pyofsDB

Read-only access to the SQLite databases produced by OF-Scraper.

Extracted from pyofscraperstash so more than one consumer can share it. The databases are treated as strictly read-only — this package never writes to them.

What it gives you

  • Discovery — find creator databases from a save location and metadata template, optionally filtered by creator or modification date.
  • Loading — copy a database into memory via SQLite's backup API before querying, which matters when the files live on NFS.
  • Schema detection — OF-Scraper's schema varies by the version that created each file; SchemaDetector reports the schema_flags a given database carries.
  • Models — SQLAlchemy models for medias, labels, profiles, models, and the five content tables (posts, stories, messages, products, others).
  • Queries — read-only helpers over those models.

Usage

import asyncio
from pyofsdb import DatabaseLoader, get_labels_by_post, get_profile_by_username


async def main() -> None:
    loader = DatabaseLoader(save_location="/data/OnlyFans")

    # Discover every creator database, or load one path directly
    for path in await loader.find_database_files():
        model_db = await loader.load_database(path)
        session = model_db["session"]

        profile = await get_profile_by_username(session, model_db["model_username"])
        if profile:
            labels = await get_labels_by_post(session, profile.user_id)
            print(model_db["model_username"], len(labels))

        await loader.dispose_model(path)

    await loader.close()


asyncio.run(main())

DatabaseLoader takes its configuration as arguments rather than reading a global:

Argument Meaning
save_location Root directory OF-Scraper writes to; substituted for {save_location}
metadata_format Template for a creator's metadata directory. Defaults to {save_location}/meta/OnlyFans/{model_username}/Metadata. A template without {model_username} denotes a combined database
models Restrict discovery to these creator usernames; omit to discover all

Schema notes

OF-Scraper's schema differs between the versions that wrote each file. Measured across 78 production databases:

  • posts appears in six distinct column shapes.
  • labels, models, and profiles are absent entirely from some databases.
  • medias may lack posted_at, duration, unlocked, hash, and model_id; the models mark these deferred so they are not selected unless accessed.
  • alembic_version is not a usable discriminator — most databases have no row, and those that do carry several different versions. Use schema_flags, which load_database returns.

profiles has no model_id column in any known database. The creator's OF id lives in profiles.user_id, and carries the same value as models.model_id.

Logging

This package logs through the standard library logging module so the consuming application keeps control of handlers. Applications using loguru can forward records with loguru's InterceptHandler pattern.

Requirements

Python >=3.12, plus sqlalchemy, aiosqlite, and greenlet.

Requirements

Requires Python: >=3.12,<4.0
Details
PyPI
2026-09-01 03:38:57 +00:00
8
Jakan
58 KiB
Assets (2)
Versions (1) View all
0.1.0 2026-09-01