SkillAgentSearch skills...

Enma

Enma is a Python library designed to fetch and download manga and doujinshi data from many sources including Manganato and NHentai.

Install / Use

/learn @AlexandreSenpai/Enma
About this skill

Quality Score

0/100

Category

Design

Supported Platforms

Universal

README

<p align="center"> <img src="./docs/images/enma.png" align="center" width="50%"> </p> <center>

PyPI download month codecov Python 3.9+ PyPI license GitHub forks GitHub stars GitHub issues

</center>

Enma

Enma is a Python library designed to fetch manga and doujinshi data from many sources. It provides a unified interface to interact with different manga repositories, making it easier to retrieve manga details, search for manga, paginate through results, and fetch random manga.

:warning: Warning

:exclamation: Important: Enma is not intended for mass querying or placing heavy loads on supported sources. Please use responsibly, adhering to the terms of service of the data sources. Misuse may result in service disruption or access denial.

Requirements

  • Python 3.9+

Installation

pip install --upgrade enma

Ensure you have the required Python version:

import sys

package_name = "enma"
python_major = "3"
python_minor = "9"

try:
    assert sys.version_info >= (int(python_major), int(python_minor))
except AssertionError:
    raise RuntimeError(f"{package_name!r} requires Python {python_major}.{python_minor}+ (You have Python {sys.version})")

Documentation

You can consult full Enma documentation at <strong><a href="https://docs.minorin.io/enma" target="_blank">https://docs.minorin.io/enma</a></strong>.

Features Comparison

Feature | NHentai | Manganato | Mangadex -----------|---------|-----------|----------- search | ✅ | ✅ | ✅ random | ✅ | 🚫 | ✅
get | ✅ | ✅ | ✅ paginate | ✅ | ✅ | ✅ download | ✅ | ✅ | ✅
author_page| ✅ | 🚫 | 🚫
set_config | ✅ | 🚫 | 🚫 caching | ✅ | ✅ | ✅

Usage

Example 1: Using Default Available Sources

from typing import cast
from enma import Enma, Sources, CloudFlareConfig, NHentai

enma = Enma[Sources]() # or just Enma()

config = NHentaiConfig(
    cloudflare=CloudFlareConfig(
        user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
        cf_clearance=''
    ),
    source=NhentaiSourceConfig(
        tiny_image_server='t1'
    ) # You can specify source configs if available
)

enma.source_manager.set_source(source_name=Sources.NHENTAI)
nh_source = cast(NHentai, enma.source_manager.source)
nh_source.set_config(config=config)

doujin = enma.random()
print(doujin)

Example 2: Extending with Custom Sources

from typing import cast
from enum import Enum
from enma import Enma, Manganato, IMangaRepository

class AvailableSources(Enum):
    NHENTAI = 'nhentai'
    MANGANATO = 'manganato'
    NEW_SOURCE = 'new-source'

enma = Enma[AvailableSources]()

enma.source_manager.add_source(source_name='new-source', source=Manganato()) # Source MUST be an instance of IMangaRepository
enma.source_manager.set_source(source_name=AvailableSources.MANGANATO)

manga = enma.random()
print(manga)

Caching

Caching is a key feature in Enma that improves your application's efficiency by storing the results of data requests. This means when the same data is requested again, Enma can quickly retrieve it from the cache instead of repeatedly calling the external source. This results in faster response times and less strain on both your application and the external APIs.

How Caching Benefits You

  • Speed: Retrieving data from the cache is faster than making a new request to a manga repository.
  • Efficiency: Reduces the number of network requests, which is especially useful when dealing with rate-limited APIs.
  • Reliability: Provides more consistent application performance even with varying network conditions.

Customizing Cache Settings

While Enma provides default caching settings that suit most needs, you may want to customize these settings based on your specific requirements, like how often you expect data to change or specific API rate limits.

Adjusting Cache Duration via Environment Variables

You can control how long data is kept in the cache by setting environment variables. This allows you to fine-tune the balance between data freshness and retrieval speed without modifying the core library code.

For example, to change the cache expiration for fetching chapters, you can set the ENMA_CACHING_FETCH_SYMBOLIC_LINK_TTL_IN_SECONDS environment variable:

# Sets the cache duration to 30 minutes
export ENMA_CACHING_FETCH_SYMBOLIC_LINK_TTL_IN_SECONDS=1800

This customization capability ensures that you can adapt the caching behavior to best fit your application's performance and efficiency needs.

By leveraging caching, Enma helps make your manga-related applications faster and more reliable, all while giving you the flexibility to tailor caching behavior as needed.

Available Caching TTL Settings

| KEY | DEFAULT | |------------------------------------------------|------------------| | ENMA_CACHING_STATE | enabled/disabled | | ENMA_CACHING_FETCH_SYMBOLIC_LINK_TTL_IN_SECONDS| 100 | | ENMA_CACHING_PAGINATE_TTL_IN_SECONDS | 100 | | ENMA_CACHING_SEARCH_TTL_IN_SECONDS | 100 | | ENMA_CACHING_GET_TTL_IN_SECONDS | 300 | | ENMA_CACHING_AUTHOR_TTL_IN_SECONDS | 100 |

Downloading Chapters

Using Enma you're able to download chapter pages to your local storage or any other storage that implements ISaverAdapter.

You can check it out how to do it right below:

from enma import (Enma,
                  CloudFlareConfig, 
                  ManganatoDownloader, 
                  Threaded, 
                  LocalStorage)

enma = Enma()
enma.source_manager.set_source('manganato')
manga = enma.get(identifier='manga-wb999684')

downloader = ManganatoDownloader()
local = LocalStorage()

if manga:
    enma.download_chapter(path=f'./download/{manga.title.english}',
                          chapter=manga.chapters[0],
                          downloader=downloader,
                          saver=local,
                          threaded=Threaded(use_threads=True,
                                            number_of_threads=5))

Using Google Drive Storage

In addition to saving chapters to local storage, Enma now supports saving chapters directly to Google Drive. This is particularly useful if you want to store your downloaded manga in the cloud for easy access across multiple devices.

Installation

To use the Google Drive storage option, you need to install additional dependencies:

pip install enma[google_drive]

Setting Up Credentials

You'll need to set up Google Drive API credentials to allow Enma to upload files to your Google Drive account. Follow these steps:

  1. Enable Google Drive API:
    • Go to the Google Cloud Console.
    • Create a new project or select an existing one.
    • Navigate to APIs & Services > Library.
    • Search for Google Drive API and click Enable.
  2. Create Service Account Credentials:
    • In the APIs & Services section, go to Credentials.
    • Click on Create Credentials > Service Account.
    • Fill in the necessary details and click Create.
    • Once the service account is created, go to it and click Keys > Add Key > Create New Key.
    • Choose JSON as the key type and download the credentials file.
  3. Share Google Drive Folder with Service Account:
    • In Google Drive, create a new folder or use an existing one.
    • Right-click the folder and select Share.
    • Share the folder with the service account's email address (found in the credentials JSON under client_email).

Example Usage

Here's how you can use the GoogleDriveStorage adapter:

from enma import (Enma,
                  ManganatoDownloader,
                  GoogleDriveStorage,
                  Threaded)

enma = Enma()
enma.source_manager.set_source('manganato')
manga = enma.get(identifier='manga-wb999684')

downloader = ManganatoDownloader()
google_drive_storage = GoogleDriveStorage(
    credentials_path='path/to/your/service_account_credentials.json',
    root_shared_folder='your_root_folder_id_in_google_drive'
)

if manga:
    enma.download_chapter(
        path=f'folder/subfolder/{manga.title.english}',
        chapter=manga.chapters[0],
        downloader=downloader,
        saver=google_drive_storage,
        threaded=Threaded(use_threads=True, number_of_threads=5)
    )

In this example:

  • Replace path/to/your/service_account_credentials.json with the path to your downloaded service account JSON credentials.
  • Replace your_root_folder_id_in_google_drive with the ID of the Google Drive folder where you want to save the chapters.
    • To get the folder ID, navigate to the folder in Google Drive and copy the ID from the URL (it's the string after folders/).
  • The path parameter specifies the folder structure within your root Google Drive folder where the chapter will be saved.

Logger Control

By default Enma sets logs as SILENT. But if you're needing to see what Enma outputs you can set log m

View on GitHub
GitHub Stars110
CategoryDesign
Updated2d ago
Forks17

Languages

Python

Security Score

100/100

Audited on Mar 27, 2026

No findings