novelai-python 0.7.0__tar.gz → 0.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {novelai_python-0.7.0 → novelai_python-0.7.2}/PKG-INFO +1 -1
- {novelai_python-0.7.0 → novelai_python-0.7.2}/pyproject.toml +1 -1
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/_enum.py +75 -34
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate_image/__init__.py +127 -24
- {novelai_python-0.7.0 → novelai_python-0.7.2}/tests/test_random_prompt.py +1 -1
- {novelai_python-0.7.0 → novelai_python-0.7.2}/LICENSE +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/NOTICE.MD +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/README.md +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_enum.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_exceptions.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/ai/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/ai/generate.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/ai/generate_image.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/ai/generate_stream.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/ai/generate_voice.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/ai/upscale.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/schema.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/user/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/user/information.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/user/login.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/user/subscription.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/credential/ApiToken.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/credential/JwtToken.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/credential/UserAuth.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/credential/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/credential/_base.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/LICENSE +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/_const.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/_cost.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/augment_image/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/augment_image/_enum.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate/_const.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate/_enum.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate/_schema.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate/themes.json +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate_image/schema.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate_image/suggest_tags.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate_stream.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate_voice/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate_voice/_enum.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/upscale.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/schema.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/user/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/user/information.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/user/login.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/user/subscription.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/server.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tokenizer/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tokenizer/clip_simple_tokenizer.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tokenizer/nerdstash_v1.model +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tokenizer/nerdstash_v2.model +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tokenizer/novelai.model +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tokenizer/novelai_v2.model +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/image_metadata/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/image_metadata/bch_utils.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/image_metadata/lsb_extractor.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/image_metadata/lsb_injector.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/paint_mask/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/random_prompt/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/random_prompt/generate_scene_composition.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/random_prompt/generate_scene_tags.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/random_prompt/generate_tags.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/utils/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/utils/encode.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/utils/useful.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/tests/__init__.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/tests/test_generate_voice.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/tests/test_server.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/tests/test_server_run.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/tests/test_tokenizer.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/tests/test_upscale.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/tests/test_user_information.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/tests/test_user_login.py +0 -0
- {novelai_python-0.7.0 → novelai_python-0.7.2}/tests/test_user_subscription.py +0 -0
|
@@ -361,6 +361,7 @@ def get_default_noise_schedule(sample_type: Sampler) -> NoiseSchedule:
|
|
|
361
361
|
|
|
362
362
|
|
|
363
363
|
def get_model_group(model: ModelTypeAlias) -> ModelGroups:
|
|
364
|
+
# 一般情况禁止转换
|
|
364
365
|
if isinstance(model, Enum):
|
|
365
366
|
model = model.value
|
|
366
367
|
else:
|
|
@@ -387,49 +388,89 @@ def get_model_group(model: ModelTypeAlias) -> ModelGroups:
|
|
|
387
388
|
return mapping.get(model, ModelGroups.STABLE_DIFFUSION)
|
|
388
389
|
|
|
389
390
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
391
|
+
@dataclass
|
|
392
|
+
class UcPrompt:
|
|
393
|
+
category: str
|
|
394
|
+
name: str
|
|
395
|
+
text: str
|
|
395
396
|
|
|
396
|
-
@dataclass
|
|
397
|
-
class UcPrompt:
|
|
398
|
-
label: str
|
|
399
|
-
text: str
|
|
400
397
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
398
|
+
def get_uc_preset(model: ModelTypeAlias) -> List[UcPrompt]:
|
|
399
|
+
prompts: List[UcPrompt] = []
|
|
400
|
+
if model in [
|
|
401
|
+
Model.SAFE_DIFFUSION,
|
|
402
|
+
Model.NAI_DIFFUSION,
|
|
403
|
+
Model.NAI_DIFFUSION_INPAINTING,
|
|
404
|
+
Model.SAFE_DIFFUSION_INPAINTING,
|
|
405
|
+
]:
|
|
406
|
+
prompts = [
|
|
407
|
+
UcPrompt(category="heavy", name="lowQualityPlusBadAnatomy",
|
|
404
408
|
text="lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"),
|
|
405
|
-
UcPrompt("lowQuality",
|
|
409
|
+
UcPrompt(category="light", name="lowQuality",
|
|
406
410
|
text="lowres, text, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"),
|
|
407
|
-
UcPrompt("none", text="lowres")
|
|
408
|
-
]
|
|
409
|
-
|
|
410
|
-
|
|
411
|
+
UcPrompt(category="none", name="none", text="lowres"),
|
|
412
|
+
]
|
|
413
|
+
elif model in [
|
|
414
|
+
Model.NAI_DIFFUSION_FURRY,
|
|
415
|
+
Model.FURRY_DIFFUSION_INPAINTING,
|
|
416
|
+
]:
|
|
417
|
+
prompts = [
|
|
418
|
+
UcPrompt(category="light", name="lowQuality",
|
|
419
|
+
text="worst quality, low quality, what has science done, what, nightmare fuel, eldritch horror, where is your god now, why"),
|
|
420
|
+
UcPrompt(category="heavy", name="badAnatomy",
|
|
421
|
+
text="{worst quality}, low quality, distracting watermark, [nightmare fuel], {{unfinished}}, deformed, outline, pattern, simple background"),
|
|
422
|
+
UcPrompt(category="none", name="none", text="low res"),
|
|
423
|
+
]
|
|
424
|
+
elif model in [
|
|
425
|
+
Model.NAI_DIFFUSION_2,
|
|
426
|
+
]:
|
|
427
|
+
prompts = [
|
|
428
|
+
UcPrompt(category="heavy", name="heavy",
|
|
411
429
|
text="lowres, bad, text, error, missing, extra, fewer, cropped, jpeg artifacts, worst quality, bad quality, watermark, displeasing, unfinished, chromatic aberration, scan, scan artifacts"),
|
|
412
|
-
UcPrompt("light",
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
430
|
+
UcPrompt(category="light", name="light",
|
|
431
|
+
text="lowres, jpeg artifacts, worst quality, watermark, blurry, very displeasing"),
|
|
432
|
+
UcPrompt(category="none", name="none", text="lowres"),
|
|
433
|
+
]
|
|
434
|
+
elif model in [
|
|
435
|
+
Model.NAI_DIFFUSION_3,
|
|
436
|
+
Model.NAI_DIFFUSION_3_INPAINTING,
|
|
437
|
+
]:
|
|
438
|
+
prompts = [
|
|
439
|
+
UcPrompt(category="heavy", name="heavy",
|
|
417
440
|
text="lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]"),
|
|
418
|
-
UcPrompt("light",
|
|
419
|
-
|
|
441
|
+
UcPrompt(category="light", name="light",
|
|
442
|
+
text="lowres, jpeg artifacts, worst quality, watermark, blurry, very displeasing"),
|
|
443
|
+
UcPrompt(category="human", name="humanFocus",
|
|
420
444
|
text="lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract], bad anatomy, bad hands, @_@, mismatched pupils, heart-shaped pupils, glowing eyes"),
|
|
421
|
-
UcPrompt("none", text="lowres")
|
|
422
|
-
]
|
|
423
|
-
|
|
424
|
-
|
|
445
|
+
UcPrompt(category="none", name="none", text="lowres"),
|
|
446
|
+
]
|
|
447
|
+
elif model in [
|
|
448
|
+
Model.NAI_DIFFUSION_FURRY_3,
|
|
449
|
+
Model.NAI_DIFFUSION_FURRY_3_INPAINTING,
|
|
450
|
+
]:
|
|
451
|
+
prompts = [
|
|
452
|
+
UcPrompt(category="heavy", name="heavy",
|
|
425
453
|
text="{{worst quality}}, [displeasing], {unusual pupils}, guide lines, {{unfinished}}, {bad}, url, artist name, {{tall image}}, mosaic, {sketch page}, comic panel, impact (font), [dated], {logo}, ych, {what}, {where is your god now}, {distorted text}, repeated text, {floating head}, {1994}, {widescreen}, absolutely everyone, sequence, {compression artifacts}, hard translated, {cropped}, {commissioner name}, unknown text, high contrast"),
|
|
426
|
-
UcPrompt("light",
|
|
454
|
+
UcPrompt(category="light", name="light",
|
|
427
455
|
text="{worst quality}, guide lines, unfinished, bad, url, tall image, widescreen, compression artifacts, unknown text"),
|
|
428
|
-
UcPrompt("none", text="lowres")
|
|
429
|
-
]
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
456
|
+
UcPrompt(category="none", name="none", text="lowres"),
|
|
457
|
+
]
|
|
458
|
+
elif model in [
|
|
459
|
+
Model.CUSTOM,
|
|
460
|
+
Model.NAI_DIFFUSION_4_CURATED_PREVIEW,
|
|
461
|
+
]:
|
|
462
|
+
prompts = [
|
|
463
|
+
UcPrompt(category="heavy", name="heavy",
|
|
464
|
+
text="blurry, lowres, error, film grain, scan artifacts, worst quality, bad quality, jpeg artifacts, very displeasing, chromatic aberration, logo, dated, signature, multiple views, gigantic breasts"),
|
|
465
|
+
UcPrompt(category="light", name="light",
|
|
466
|
+
text="blurry, lowres, error, worst quality, bad quality, jpeg artifacts, very displeasing, logo, dated, signature"),
|
|
467
|
+
UcPrompt(category="none", name="none", text=""),
|
|
468
|
+
]
|
|
469
|
+
return prompts
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
def get_default_uc_preset(model: ModelTypeAlias, uc_preset: int) -> str:
|
|
473
|
+
prompts = get_uc_preset(model)
|
|
433
474
|
if 0 <= uc_preset < len(prompts):
|
|
434
475
|
return prompts[uc_preset].text
|
|
435
476
|
else:
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate_image/__init__.py
RENAMED
|
@@ -6,7 +6,9 @@ import base64
|
|
|
6
6
|
import json
|
|
7
7
|
import math
|
|
8
8
|
import random
|
|
9
|
+
import re
|
|
9
10
|
from copy import deepcopy
|
|
11
|
+
from enum import Enum
|
|
10
12
|
from io import BytesIO
|
|
11
13
|
from typing import Optional, Union, Tuple, List
|
|
12
14
|
from urllib.parse import urlparse
|
|
@@ -28,7 +30,7 @@ from novelai_python.sdk.ai._enum import Model, Sampler, NoiseSchedule, ControlNe
|
|
|
28
30
|
INPAINTING_MODEL_LIST, get_default_uc_preset, \
|
|
29
31
|
ModelTypeAlias, UCPresetTypeAlias, get_default_noise_schedule, get_supported_noise_schedule, \
|
|
30
32
|
get_model_group, ModelGroups, get_supported_params, get_modifiers, ImageBytesTypeAlias
|
|
31
|
-
from .schema import Character, V4Prompt, V4NegativePrompt
|
|
33
|
+
from .schema import Character, V4Prompt, V4NegativePrompt, PositionMap
|
|
32
34
|
from ...schema import ApiBaseModel
|
|
33
35
|
from ...._exceptions import APIError, AuthError, ConcurrentGenerationError, SessionHttpError
|
|
34
36
|
from ...._response.ai.generate_image import ImageGenerateResp, RequestParams
|
|
@@ -110,7 +112,7 @@ class Params(BaseModel):
|
|
|
110
112
|
Overlay Original Image.Prevents the existing image from changing,
|
|
111
113
|
but can introduce seams along the edge of the mask.
|
|
112
114
|
"""
|
|
113
|
-
use_coords: bool = Field(
|
|
115
|
+
use_coords: bool = Field(False, description="Use Coordinates")
|
|
114
116
|
"""Use Coordinates"""
|
|
115
117
|
characterPrompts: List[Character] = Field(default_factory=list)
|
|
116
118
|
"""Character Prompts"""
|
|
@@ -342,6 +344,35 @@ class Params(BaseModel):
|
|
|
342
344
|
|
|
343
345
|
class GenerateImageInfer(ApiBaseModel):
|
|
344
346
|
_endpoint: str = PrivateAttr("https://image.novelai.net")
|
|
347
|
+
_mutual_exclusion: bool = PrivateAttr(False)
|
|
348
|
+
"""Positive words and negative words are mutually exclusive, and conflicting negative words are deleted first."""
|
|
349
|
+
_quality_modifier: bool = PrivateAttr(True)
|
|
350
|
+
"""Add Quality Modifier To Input"""
|
|
351
|
+
|
|
352
|
+
def set_mutual_exclusion(self, value: bool):
|
|
353
|
+
"""
|
|
354
|
+
**Enable This will modify the negative prompt.**
|
|
355
|
+
Default is False.
|
|
356
|
+
|
|
357
|
+
Positive words and negative words are mutually exclusive, and conflicting negative words are deleted first.
|
|
358
|
+
:param value: bool
|
|
359
|
+
:return: self
|
|
360
|
+
"""
|
|
361
|
+
self._mutual_exclusion = bool(value)
|
|
362
|
+
return self
|
|
363
|
+
|
|
364
|
+
def set_quality_modifier(self, value: bool):
|
|
365
|
+
"""
|
|
366
|
+
**Enable This will modify the input prompt.**
|
|
367
|
+
Default is True.
|
|
368
|
+
|
|
369
|
+
Add Quality Modifier To Input.
|
|
370
|
+
Whether to add the quality vocabulary used by the web application.
|
|
371
|
+
:param value:
|
|
372
|
+
:return:
|
|
373
|
+
"""
|
|
374
|
+
self._quality_modifier = bool(value)
|
|
375
|
+
return self
|
|
345
376
|
|
|
346
377
|
@property
|
|
347
378
|
def endpoint(self):
|
|
@@ -371,15 +402,75 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
371
402
|
|
|
372
403
|
# Add negative prompt based on ucPreset
|
|
373
404
|
if self.parameters.ucPreset is not None:
|
|
374
|
-
|
|
405
|
+
uc_preset = self.parameters.ucPreset
|
|
406
|
+
# If ucPreset is Enum, get the value
|
|
407
|
+
if isinstance(self.parameters.ucPreset, Enum):
|
|
408
|
+
uc_preset = self.parameters.ucPreset.value
|
|
409
|
+
default_negative_prompt = get_default_uc_preset(self.model, uc_preset)
|
|
375
410
|
self.parameters.negative_prompt = ", ".join(
|
|
376
411
|
filter(None, [default_negative_prompt, self.parameters.negative_prompt])
|
|
377
412
|
)
|
|
378
413
|
|
|
379
|
-
# Add quality prompt
|
|
414
|
+
# Add quality prompt based on qualityToggle
|
|
380
415
|
modifier = get_modifiers(self.model)
|
|
381
|
-
|
|
382
|
-
|
|
416
|
+
quality_tags, suffix = modifier.qualityTags, modifier.suffix
|
|
417
|
+
|
|
418
|
+
def enhance_text_part(_part, _quality_tags, _suffix):
|
|
419
|
+
text_parts = _part.split(" Text:")
|
|
420
|
+
enhanced_text_parts = [
|
|
421
|
+
_quality_tags + text_part + _suffix + ('.' if _suffix and len(text_parts) > 1 else '')
|
|
422
|
+
if index == 0
|
|
423
|
+
else text_part
|
|
424
|
+
for index, text_part in enumerate(text_parts)
|
|
425
|
+
]
|
|
426
|
+
return " Text:".join(enhanced_text_parts)
|
|
427
|
+
|
|
428
|
+
def enhance_simple_part(_part, _quality_tags, _suffix):
|
|
429
|
+
match = re.search(r"(:[\d.]+$)", _part)
|
|
430
|
+
matched_value = match.group(0) if match else None
|
|
431
|
+
core_part = _part[:-len(matched_value)] if matched_value else _part
|
|
432
|
+
return _quality_tags + core_part + _suffix + (matched_value or "")
|
|
433
|
+
|
|
434
|
+
def enhance_message(_prompt):
|
|
435
|
+
try:
|
|
436
|
+
if get_supported_params(self.model).characterPrompts:
|
|
437
|
+
parts = _prompt.split("|")
|
|
438
|
+
enhanced_parts = [
|
|
439
|
+
quality_tags + part + suffix
|
|
440
|
+
if index == 0 and not get_supported_params(self.model).text
|
|
441
|
+
else enhance_text_part(part, quality_tags, suffix)
|
|
442
|
+
if index == 0
|
|
443
|
+
else part
|
|
444
|
+
for index, part in enumerate(parts)
|
|
445
|
+
]
|
|
446
|
+
return "|".join(enhanced_parts)
|
|
447
|
+
else:
|
|
448
|
+
parts = _prompt.split("|")
|
|
449
|
+
enhanced_parts = [
|
|
450
|
+
enhance_simple_part(part, quality_tags, suffix)
|
|
451
|
+
for part in parts
|
|
452
|
+
]
|
|
453
|
+
return "|".join(enhanced_parts)
|
|
454
|
+
except Exception as e:
|
|
455
|
+
logger.error(
|
|
456
|
+
f"Failed to enhance `{_prompt}` because {e},"
|
|
457
|
+
f"Report this issue to https://github.com/LLMKIRA/novelai-python/issues"
|
|
458
|
+
)
|
|
459
|
+
return _prompt
|
|
460
|
+
|
|
461
|
+
if self._quality_modifier:
|
|
462
|
+
logger.trace("Enhancing input with quality modifier, will modify input prompt.")
|
|
463
|
+
self.input = enhance_message(self.input)
|
|
464
|
+
|
|
465
|
+
if self._mutual_exclusion:
|
|
466
|
+
logger.trace("Mutual exclusion is enabled, will modify negative prompt.")
|
|
467
|
+
input_prompt = {x.strip(): x for x in self.input.split(",")}
|
|
468
|
+
uc_prompt = {x.strip(): x for x in self.parameters.negative_prompt.split(",")}
|
|
469
|
+
# Remove conflicting negative words
|
|
470
|
+
for key in input_prompt:
|
|
471
|
+
if key in uc_prompt:
|
|
472
|
+
uc_prompt.pop(key)
|
|
473
|
+
self.parameters.negative_prompt = ",".join(uc_prompt.values())
|
|
383
474
|
|
|
384
475
|
@model_validator(mode="after")
|
|
385
476
|
def _build_nai4_prompt(self):
|
|
@@ -417,7 +508,9 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
417
508
|
@model_validator(mode="after")
|
|
418
509
|
def _backend_logic(self):
|
|
419
510
|
"""
|
|
420
|
-
|
|
511
|
+
Calibration results.
|
|
512
|
+
|
|
513
|
+
**NOTE: It is forbidden to write logic that does not belong to novelai.net here**
|
|
421
514
|
:return: self
|
|
422
515
|
"""
|
|
423
516
|
if self.action == Action.GENERATE:
|
|
@@ -464,7 +557,30 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
464
557
|
self.parameters.sm_dyn = True
|
|
465
558
|
|
|
466
559
|
if self.parameters.sm_dyn and (not self.parameters.sm):
|
|
467
|
-
self.parameters.
|
|
560
|
+
self.parameters.sm = True
|
|
561
|
+
|
|
562
|
+
# AUTO SMEA SETTING
|
|
563
|
+
"""
|
|
564
|
+
def sm_size_cast(model: Model):
|
|
565
|
+
if model in [
|
|
566
|
+
Model.NAI_DIFFUSION_V3,
|
|
567
|
+
Model.NAI_DIFFUSION_V3_INPAINTING,
|
|
568
|
+
Model.NAI_DIFFUSION_FURRY_V3,
|
|
569
|
+
Model.NAI_DIFFUSION_FURRY_V3_INPAINTING,
|
|
570
|
+
Model.CUSTOM
|
|
571
|
+
]:
|
|
572
|
+
return 2166785
|
|
573
|
+
return 1064961
|
|
574
|
+
if self.parameters.autoSmea and (self.parameters.width * self.parameters.height < sm_size_cast(self.model)):
|
|
575
|
+
self.parameters.autoSmea = False
|
|
576
|
+
"""
|
|
577
|
+
|
|
578
|
+
if self.parameters.characterPrompts:
|
|
579
|
+
self.parameters.use_coords = any([c.center != PositionMap.AUTO for c in self.parameters.characterPrompts])
|
|
580
|
+
|
|
581
|
+
# Mix Prompt Warning
|
|
582
|
+
if self.input.count('|') > 6:
|
|
583
|
+
logger.warning("Maximum prompt mixes exceeded. Extra will be ignored.")
|
|
468
584
|
|
|
469
585
|
if self.parameters.sampler in [
|
|
470
586
|
Sampler.DDIM,
|
|
@@ -572,7 +688,6 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
572
688
|
prompt: str,
|
|
573
689
|
*,
|
|
574
690
|
model: Union[Model, str],
|
|
575
|
-
qualitySuffix: bool = True,
|
|
576
691
|
negative_prompt: str = "",
|
|
577
692
|
ucPreset: UCPresetTypeAlias = UCPreset.TYPE0,
|
|
578
693
|
sm: bool = False,
|
|
@@ -602,7 +717,6 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
602
717
|
:param prompt: Given prompt.
|
|
603
718
|
:param model: Model for generation.
|
|
604
719
|
:param negative_prompt: The things you don't want to see in the image.
|
|
605
|
-
:param qualitySuffix: Add quality suffix to prompt
|
|
606
720
|
:param ucPreset: The negative prompt preset.
|
|
607
721
|
:param steps: The steps for generation.
|
|
608
722
|
:param seed: The seed for generation.
|
|
@@ -619,9 +733,6 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
619
733
|
"""
|
|
620
734
|
if character_prompts is None:
|
|
621
735
|
character_prompts = []
|
|
622
|
-
if qualitySuffix:
|
|
623
|
-
modifier = get_modifiers(model)
|
|
624
|
-
prompt += modifier.suffix
|
|
625
736
|
if seed is None:
|
|
626
737
|
seed = random.randint(0, 4294967295 - 7)
|
|
627
738
|
if reference_strength_multiple is None:
|
|
@@ -668,7 +779,6 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
668
779
|
seed: int = None,
|
|
669
780
|
extra_noise_seed: int = None,
|
|
670
781
|
model: Union[Model, str] = Model.NAI_DIFFUSION_3,
|
|
671
|
-
qualitySuffix: bool = True,
|
|
672
782
|
negative_prompt: str = "",
|
|
673
783
|
ucPreset: UCPresetTypeAlias = UCPreset.TYPE0,
|
|
674
784
|
steps: int = 23,
|
|
@@ -699,7 +809,6 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
699
809
|
:param prompt: Given prompt.
|
|
700
810
|
:param model: Model for generation.
|
|
701
811
|
:param negative_prompt: The things you don't want to see in the image.
|
|
702
|
-
:param qualitySuffix: Add quality suffix to prompt
|
|
703
812
|
:param ucPreset: The negative prompt preset.
|
|
704
813
|
:param steps: The steps for generation.
|
|
705
814
|
:param seed: The seed for generation.
|
|
@@ -716,9 +825,6 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
716
825
|
"""
|
|
717
826
|
if character_prompts is None:
|
|
718
827
|
character_prompts = []
|
|
719
|
-
if qualitySuffix:
|
|
720
|
-
modifier = get_modifiers(model)
|
|
721
|
-
prompt += modifier.suffix
|
|
722
828
|
if seed is None:
|
|
723
829
|
seed = random.randint(0, 4294967295 - 7)
|
|
724
830
|
if extra_noise_seed is None:
|
|
@@ -768,7 +874,6 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
768
874
|
mask: Union[bytes, str],
|
|
769
875
|
strength: float = 0.7,
|
|
770
876
|
model: Union[Model, str] = Model.NAI_DIFFUSION_3,
|
|
771
|
-
qualitySuffix: bool = True,
|
|
772
877
|
negative_prompt: str = "",
|
|
773
878
|
ucPreset: UCPresetTypeAlias = UCPreset.TYPE0,
|
|
774
879
|
steps: int = 23,
|
|
@@ -799,7 +904,6 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
799
904
|
:param prompt: Given prompt.
|
|
800
905
|
:param model: Model for generation.
|
|
801
906
|
:param negative_prompt: The things you don't want to see in the image.
|
|
802
|
-
:param qualitySuffix: Add quality suffix to prompt
|
|
803
907
|
:param ucPreset: The negative prompt preset.
|
|
804
908
|
:param steps: The steps for generation.
|
|
805
909
|
:param seed: The seed for generation.
|
|
@@ -816,9 +920,6 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
816
920
|
"""
|
|
817
921
|
if character_prompts is None:
|
|
818
922
|
character_prompts = []
|
|
819
|
-
if qualitySuffix:
|
|
820
|
-
modifier = get_modifiers(model)
|
|
821
|
-
prompt += modifier.suffix
|
|
822
923
|
if seed is None:
|
|
823
924
|
seed = random.randint(0, 4294967295 - 7)
|
|
824
925
|
if reference_strength_multiple is None:
|
|
@@ -891,7 +992,9 @@ class GenerateImageInfer(ApiBaseModel):
|
|
|
891
992
|
override_headers: Optional[dict] = None,
|
|
892
993
|
) -> ImageGenerateResp:
|
|
893
994
|
"""
|
|
894
|
-
Generate images using NovelAI's diffusion models
|
|
995
|
+
**Generate images using NovelAI's diffusion models.**
|
|
996
|
+
|
|
997
|
+
According to our Terms of Service, all generation requests must be initiated by a human action. Automating text or image generation to create excessive load on our systems is not allowed.
|
|
895
998
|
|
|
896
999
|
:param override_headers: the headers to override
|
|
897
1000
|
:param session: session
|
|
@@ -58,4 +58,4 @@ def test_get_holiday_themed_tags():
|
|
|
58
58
|
result_m = generator.get_holiday_themed_tags()
|
|
59
59
|
result_f = generator.get_holiday_themed_tags()
|
|
60
60
|
result_o = generator.get_holiday_themed_tags()
|
|
61
|
-
assert result_m
|
|
61
|
+
assert len({result_m, result_f, result_o}) != 1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/ai/generate_image.py
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/ai/generate_stream.py
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/ai/generate_voice.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/user/information.py
RENAMED
|
File without changes
|
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/_response/user/subscription.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/augment_image/__init__.py
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/augment_image/_enum.py
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate/themes.json
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate_image/schema.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate_voice/__init__.py
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/sdk/ai/generate_voice/_enum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tokenizer/clip_simple_tokenizer.py
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tokenizer/nerdstash_v1.model
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tokenizer/nerdstash_v2.model
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/image_metadata/__init__.py
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/image_metadata/bch_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/image_metadata/lsb_injector.py
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/paint_mask/__init__.py
RENAMED
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/random_prompt/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{novelai_python-0.7.0 → novelai_python-0.7.2}/src/novelai_python/tool/random_prompt/generate_tags.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|