🎨 A lightweight async Python API for NovelAI image generation and director tools.
Project description
🐾 NekoAI-API
A lightweight async Python client for NovelAI image generation, with first-class support for the V4.5 models.
Overview
NekoAI-API wraps NovelAI's image generation API in a clean, typed, asyncio-based Python interface. It centers on the V4.5 model family — multi-character prompts with positioning, real-time generation streaming, vibe transfer with automatic encoding — while remaining fully compatible with V4 and V3.
Request payloads are validated with pydantic and verified field-by-field against payloads captured from the NovelAI web client, so what this library sends is what the website sends.
| ✨ V4.5 first | Full/Curated models, multi-character prompts with coordinates, character-level undesired content |
| 🎬 Real-time streaming | Watch every denoising step as an async event stream |
| 🖌️ All actions | Text-to-image, img2img, inpainting, vibe transfer (auto vibe encoding with caching) |
| 🛠️ Director tools | Line art, sketch, background removal, declutter, colorize, emotion change |
| 🔧 Utilities | Upscaling, tag suggestions, ControlNet annotation, subscription/Anlas info |
| 🖥️ CLI | nekoai command covering generation, tools, and account queries |
| 🌐 Custom hosts | Point image and account endpoints at your own reverse proxy or gateway |
[!NOTE] This project is licensed under AGPL-3.0. It was originally inspired by HanaokaYuzu/NovelAI-API and adopts a copyleft license accordingly.
Supported Models
| Model | Enum | Inpainting variant |
|---|---|---|
| NAI Diffusion V4.5 Full (recommended) | Model.V4_5 |
Model.V4_5_INP |
| NAI Diffusion V4.5 Curated | Model.V4_5_CUR |
Model.V4_5_CUR_INP |
| NAI Diffusion V4 Full | Model.V4 |
Model.V4_INP |
| NAI Diffusion V4 Curated | Model.V4_CUR |
Model.V4_CUR_INP |
| NAI Diffusion V3 | Model.V3 |
Model.V3_INP |
| NAI Diffusion Furry V3 | Model.FURRY |
Model.FURRY_INP |
Installation
Requires Python 3.10+.
pip install -U nekoai-api
# or
uv add nekoai-api
Quick Start
import asyncio
from nekoai import Model, NovelAI, Resolution
async def main():
async with NovelAI(token="your_access_token") as client:
images = await client.generate_image(
prompt="1girl, silver hair, blue eyes, white dress, flower garden",
model=Model.V4_5,
res_preset=Resolution.NORMAL_PORTRAIT,
)
for image in images:
image.save("output")
asyncio.run(main())
Authentication accepts a direct access token (recommended — generate one with
nekoai login <username> <password>) or a username/password pair. The client
initializes itself on first use; call client.init(...) only if you need a custom
timeout or auto-close behavior. Pass verbose=True to log the estimated Anlas cost
of each generation.
Image Generation
generate_image accepts parameters directly or a prepared Metadata object.
Quality tags and undesired-content presets are applied automatically per model
(disable with qualityToggle=False / ucPreset=3).
from nekoai import Metadata, Model, NovelAI, Resolution, Sampler
metadata = Metadata(
prompt="1girl, cute, anime style, detailed",
negative_prompt="lowres, blurry",
model=Model.V4_5,
res_preset=Resolution.NORMAL_PORTRAIT,
sampler=Sampler.EULER_ANC,
steps=28,
scale=6.0,
seed=1234567890,
)
images = await client.generate_image(metadata)
Multi-Character Prompts (V4/V4.5)
Each character gets its own prompt, undesired content, and canvas position:
from nekoai import CharacterPrompt, Model, PositionCoords, Resolution
images = await client.generate_image(
prompt="two people standing together, park background",
model=Model.V4_5,
res_preset=Resolution.NORMAL_LANDSCAPE,
characterPrompts=[
CharacterPrompt(
prompt="girl, red hair, red dress",
uc="bad hands, bad anatomy",
center=PositionCoords(x=0.3, y=0.5),
),
CharacterPrompt(
prompt="boy, blue hair, blue uniform",
uc="bad hands, bad anatomy",
center=PositionCoords(x=0.7, y=0.5),
),
],
)
Real-time Streaming (V4/V4.5)
With stream=True, generate_image returns an async event stream so you can watch
each denoising step — useful for progress UIs and timelapses:
from nekoai import EventType
async for event in await client.generate_image(
prompt="1girl, cute, anime style",
model=Model.V4_5,
res_preset=Resolution.NORMAL_PORTRAIT,
stream=True,
):
if event.event_type == EventType.INTERMEDIATE:
print(f"step {event.step_ix} (sigma={event.sigma:.2f})")
elif event.event_type == EventType.FINAL:
event.image.save("output", "final.png")
In batch mode (stream=False, the default) the same call returns list[Image]
once generation completes. V3 models always return final images directly.
Image to Image
from nekoai import Action, Model
from nekoai.utils import parse_image
width, height, base64_image = parse_image("input/source.png")
images = await client.generate_image(
prompt="1girl, fantasy outfit",
model=Model.V4_5,
action=Action.IMG2IMG,
width=width,
height=height,
image=base64_image,
strength=0.5, # lower = closer to the original
noise=0.1,
)
Inpainting
Provide a base image and a black/white mask (white areas are repainted) and use an inpainting model:
from nekoai import Action, Model
from nekoai.utils import parse_image
width, height, base64_image = parse_image("input/portrait.png")
_, _, base64_mask = parse_image("input/mask.png")
images = await client.generate_image(
prompt="1girl, detailed background",
model=Model.V4_5_INP,
action=Action.INPAINT,
width=width,
height=height,
image=base64_image,
mask=base64_mask,
add_original_image=True, # overlay untouched pixels from the original
)
Vibe Transfer
Borrow the style and mood of reference images. For V4/V4.5 models the client
encodes references through /ai/encode-vibe automatically (2 Anlas per new image;
results are cached for the client's lifetime):
from nekoai import Model, Resolution
from nekoai.utils import parse_image
_, _, reference = parse_image("input/style_reference.png")
images = await client.generate_image(
prompt="landscape, mountains, sunset",
model=Model.V4_5,
res_preset=Resolution.NORMAL_LANDSCAPE,
reference_image_multiple=[reference],
reference_information_extracted_multiple=[1.0],
reference_strength_multiple=[0.7],
)
Director Tools
Every Director tool is a single method call. Image inputs accept a file path,
pathlib.Path, raw bytes, a file-like object, or a base64 string.
from nekoai import EmotionLevel, EmotionOptions
result = await client.lineart("image.png") # image -> line art
result = await client.sketch("image.png") # image -> sketch
result = await client.background_removal("image.png") # remove background (costs Anlas)
result = await client.declutter("image.png") # remove text/artifacts
result = await client.colorize("lineart.png", prompt="silver hair, blue eyes")
result = await client.change_emotion(
"image.png",
emotion=EmotionOptions.HAPPY,
emotion_level=EmotionLevel.NORMAL,
)
result.save("output")
Utilities
# Upscale 2x or 4x (costs Anlas)
upscaled = await client.upscale("image.png", scale=4)
# Tag autocomplete
tags = await client.suggest_tags("blue hai") # [{"tag": "blue hair", "count": ...}, ...]
# ControlNet condition masks (edge/depth preprocessing).
# Note: ControlNet-guided generation is a V1/V2-era feature not supported by V3+.
from nekoai import Controlnet
mask = await client.annotate_image("image.png", model=Controlnet.SCRIBBLER)
# Subscription tier and Anlas balance
subscription = await client.get_subscription()
user_data = await client.get_user_data()
Command Line Interface
The nekoai command covers generation, tools, and account queries. Authentication
comes from --token, the NAI_TOKEN environment variable, or
--username/--password.
nekoai login <username> <password> # exchange credentials for a token
export NAI_TOKEN="your_access_token"
nekoai generate "1girl, cute" -m v4_5 -s 832x1216 --steps 28 -n 2
nekoai generate "1girl, cute" --stream # live step progress (V4/V4.5)
nekoai tool lineart image.png # also: sketch, bg-removal, declutter,
nekoai tool emotion image.png --emotion happy # colorize, emotion, annotate
nekoai upscale image.png --scale 4
nekoai tags "blue hai"
nekoai subscription
Custom Hosts
Both the image host and the account host can point at a custom base URL (reverse
proxy, self-hosted gateway). The Host header is derived from the URL automatically.
client = NovelAI(
token="your_access_token",
host="https://your-image-proxy.example.com", # default: https://image.novelai.net
api_host="https://your-api-proxy.example.com", # default: https://api.novelai.net
)
Examples
One runnable script per feature lives in examples/requests/,
each reading NAI_TOKEN from the environment — see its
README for the full index and per-feature Anlas costs.
References
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nekoai_api-0.4.0.tar.gz.
File metadata
- Download URL: nekoai_api-0.4.0.tar.gz
- Upload date:
- Size: 46.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c865085b93917ddcc44615cbca1103bcca5e6feb2cf8048780acc8f8cc26575d
|
|
| MD5 |
af570d8dcc100891cbfc4a0d0e63a593
|
|
| BLAKE2b-256 |
a8228b4b72fe09407c1edd63cfe790827b80453c3ff2b406a0beee3816762732
|
Provenance
The following attestation bundles were made for nekoai_api-0.4.0.tar.gz:
Publisher:
publish.yml on Nya-Foundation/NekoAI-API
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nekoai_api-0.4.0.tar.gz -
Subject digest:
c865085b93917ddcc44615cbca1103bcca5e6feb2cf8048780acc8f8cc26575d - Sigstore transparency entry: 1781414261
- Sigstore integration time:
-
Permalink:
Nya-Foundation/NekoAI-API@f75ff84ba6262ae8bf4345f2246ed4db6ba064a5 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Nya-Foundation
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f75ff84ba6262ae8bf4345f2246ed4db6ba064a5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file nekoai_api-0.4.0-py3-none-any.whl.
File metadata
- Download URL: nekoai_api-0.4.0-py3-none-any.whl
- Upload date:
- Size: 49.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e503ecf5e23f341aa435fdebeb8df19c007f5365457373c8e4bc1a2de8799bc4
|
|
| MD5 |
24cb90504dd705918e4a7c98833ba058
|
|
| BLAKE2b-256 |
169ff34ace1e975ae1c802d9d2d4f046de9d7de5b73d2ef30c863f21fa4439cf
|
Provenance
The following attestation bundles were made for nekoai_api-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on Nya-Foundation/NekoAI-API
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nekoai_api-0.4.0-py3-none-any.whl -
Subject digest:
e503ecf5e23f341aa435fdebeb8df19c007f5365457373c8e4bc1a2de8799bc4 - Sigstore transparency entry: 1781414337
- Sigstore integration time:
-
Permalink:
Nya-Foundation/NekoAI-API@f75ff84ba6262ae8bf4345f2246ed4db6ba064a5 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Nya-Foundation
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f75ff84ba6262ae8bf4345f2246ed4db6ba064a5 -
Trigger Event:
push
-
Statement type: