novelai-python 0.4.7__tar.gz → 0.4.9__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.
Files changed (77) hide show
  1. {novelai_python-0.4.7 → novelai_python-0.4.9}/PKG-INFO +9 -6
  2. {novelai_python-0.4.7 → novelai_python-0.4.9}/README.md +7 -4
  3. {novelai_python-0.4.7 → novelai_python-0.4.9}/pyproject.toml +2 -2
  4. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/ai/generate_image.py +5 -4
  5. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate/__init__.py +6 -6
  6. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate/_enum.py +2 -2
  7. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate_image/__init__.py +3 -3
  8. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate_image/_enum.py +13 -5
  9. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/server.py +5 -2
  10. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tool/image_metadata/__init__.py +28 -3
  11. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tool/paint_mask/__init__.py +7 -6
  12. {novelai_python-0.4.7 → novelai_python-0.4.9}/LICENSE +0 -0
  13. {novelai_python-0.4.7 → novelai_python-0.4.9}/NOTICE.MD +0 -0
  14. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/__init__.py +0 -0
  15. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_exceptions.py +0 -0
  16. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/__init__.py +0 -0
  17. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/ai/__init__.py +0 -0
  18. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/ai/generate.py +0 -0
  19. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/ai/generate_stream.py +0 -0
  20. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/ai/generate_voice.py +0 -0
  21. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/ai/upscale.py +0 -0
  22. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/schema.py +0 -0
  23. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/user/__init__.py +0 -0
  24. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/user/information.py +0 -0
  25. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/user/login.py +0 -0
  26. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/_response/user/subscription.py +0 -0
  27. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/credential/ApiToken.py +0 -0
  28. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/credential/JwtToken.py +0 -0
  29. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/credential/UserAuth.py +0 -0
  30. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/credential/__init__.py +0 -0
  31. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/credential/_base.py +0 -0
  32. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/__init__.py +0 -0
  33. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/LICENSE +0 -0
  34. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/__init__.py +0 -0
  35. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate/_const.py +0 -0
  36. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate/_preset.py +0 -0
  37. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate_image/_const.py +0 -0
  38. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate_image/suggest_tags.py +0 -0
  39. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate_stream.py +0 -0
  40. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate_voice/__init__.py +0 -0
  41. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/generate_voice/_enum.py +0 -0
  42. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/ai/upscale.py +0 -0
  43. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/schema.py +0 -0
  44. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/user/__init__.py +0 -0
  45. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/user/information.py +0 -0
  46. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/user/login.py +0 -0
  47. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/sdk/user/subscription.py +0 -0
  48. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/NOTICE.MD +0 -0
  49. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/__init__.py +0 -0
  50. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/bpe_simple_vocab_16e6.txt.gz +0 -0
  51. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/gpt2-genji_tokenizer.json +0 -0
  52. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/gpt2_tokenizer.json +0 -0
  53. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/nerdstash_v1.model +0 -0
  54. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/nerdstash_v2.model +0 -0
  55. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/novelai.model +0 -0
  56. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/novelai_v2.model +0 -0
  57. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/pile_tokenizer.json +0 -0
  58. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tokenizer/simple_tokenizer.py +0 -0
  59. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tool/__init__.py +0 -0
  60. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tool/image_metadata/lsb_extractor.py +0 -0
  61. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tool/image_metadata/lsb_injector.py +0 -0
  62. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tool/random_prompt/__init__.py +0 -0
  63. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tool/random_prompt/tag.py +0 -0
  64. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tool/random_prompt/tag_character.py +0 -0
  65. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/tool/random_prompt/tag_nsfw.py +0 -0
  66. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/utils/__init__.py +0 -0
  67. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/utils/encode.py +0 -0
  68. {novelai_python-0.4.7 → novelai_python-0.4.9}/src/novelai_python/utils/useful.py +0 -0
  69. {novelai_python-0.4.7 → novelai_python-0.4.9}/tests/__init__.py +0 -0
  70. {novelai_python-0.4.7 → novelai_python-0.4.9}/tests/test_generate_voice.py +0 -0
  71. {novelai_python-0.4.7 → novelai_python-0.4.9}/tests/test_random_prompt.py +0 -0
  72. {novelai_python-0.4.7 → novelai_python-0.4.9}/tests/test_server.py +0 -0
  73. {novelai_python-0.4.7 → novelai_python-0.4.9}/tests/test_server_run.py +0 -0
  74. {novelai_python-0.4.7 → novelai_python-0.4.9}/tests/test_upscale.py +0 -0
  75. {novelai_python-0.4.7 → novelai_python-0.4.9}/tests/test_user_information.py +0 -0
  76. {novelai_python-0.4.7 → novelai_python-0.4.9}/tests/test_user_login.py +0 -0
  77. {novelai_python-0.4.7 → novelai_python-0.4.9}/tests/test_user_subscription.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: novelai-python
3
- Version: 0.4.7
3
+ Version: 0.4.9
4
4
  Summary: NovelAI Python Binding With Pydantic
5
5
  Author-Email: sudoskys <coldlando@hotmail.com>
6
6
  License: Apache License 2.0
7
7
  Project-URL: Repository, https://github.com/LlmKira/novelai-python/
8
8
  Project-URL: Issues, https://github.com/LlmKira/novelai-python/issues
9
- Requires-Python: >=3.8
9
+ Requires-Python: >=3.9
10
10
  Requires-Dist: elara>=0.5.5
11
11
  Requires-Dist: loguru>=0.7.2
12
12
  Requires-Dist: pydantic-settings>=2.1.0
@@ -43,6 +43,8 @@ Description-Content-Type: text/markdown
43
43
 
44
44
  The goal of this repository is to use Pydantic to build legitimate requests to access the NovelAI API service.
45
45
 
46
+ > Python >= 3.9 is required.
47
+
46
48
  ### Roadmap 🚧
47
49
 
48
50
  - [x] tool.random_prompt
@@ -113,17 +115,18 @@ import asyncio
113
115
  import os
114
116
 
115
117
  from dotenv import load_dotenv
118
+ from pydantic import SecretStr
116
119
 
117
- from novelai_python import APIError, Login
120
+ from novelai_python import APIError, LoginCredential
118
121
  from novelai_python.sdk.ai.generate import TextLLMModel, LLM
119
122
 
120
123
  load_dotenv()
121
124
  username = os.getenv("NOVELAI_USER", None)
122
125
  assert username is not None
123
126
  # credential = JwtCredential(jwt_token=SecretStr(jwt))
124
- login_credential = Login.build(
125
- user_name=os.getenv("NOVELAI_USER"),
126
- password=os.getenv("NOVELAI_PASS")
127
+ login_credential = LoginCredential(
128
+ username=os.getenv("NOVELAI_USER"),
129
+ password=SecretStr(os.getenv("NOVELAI_PASS"))
127
130
  )
128
131
 
129
132
 
@@ -9,6 +9,8 @@
9
9
 
10
10
  The goal of this repository is to use Pydantic to build legitimate requests to access the NovelAI API service.
11
11
 
12
+ > Python >= 3.9 is required.
13
+
12
14
  ### Roadmap 🚧
13
15
 
14
16
  - [x] tool.random_prompt
@@ -79,17 +81,18 @@ import asyncio
79
81
  import os
80
82
 
81
83
  from dotenv import load_dotenv
84
+ from pydantic import SecretStr
82
85
 
83
- from novelai_python import APIError, Login
86
+ from novelai_python import APIError, LoginCredential
84
87
  from novelai_python.sdk.ai.generate import TextLLMModel, LLM
85
88
 
86
89
  load_dotenv()
87
90
  username = os.getenv("NOVELAI_USER", None)
88
91
  assert username is not None
89
92
  # credential = JwtCredential(jwt_token=SecretStr(jwt))
90
- login_credential = Login.build(
91
- user_name=os.getenv("NOVELAI_USER"),
92
- password=os.getenv("NOVELAI_PASS")
93
+ login_credential = LoginCredential(
94
+ username=os.getenv("NOVELAI_USER"),
95
+ password=SecretStr(os.getenv("NOVELAI_PASS"))
93
96
  )
94
97
 
95
98
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "novelai-python"
3
- version = "0.4.7"
3
+ version = "0.4.9"
4
4
  description = "NovelAI Python Binding With Pydantic"
5
5
  authors = [
6
6
  { name = "sudoskys", email = "coldlando@hotmail.com" },
@@ -27,7 +27,7 @@ dependencies = [
27
27
  "regex>=2023.12.25",
28
28
  "tokenizers>=0.15.2",
29
29
  ]
30
- requires-python = ">=3.8"
30
+ requires-python = ">=3.9"
31
31
  readme = "README.md"
32
32
 
33
33
  [project.license]
@@ -10,11 +10,12 @@ from pydantic import BaseModel
10
10
  from ..schema import RespBase
11
11
 
12
12
 
13
- class ImageGenerateResp(RespBase):
14
- class RequestParams(BaseModel):
15
- endpoint: str
16
- raw_request: dict = None
13
+ class RequestParams(BaseModel):
14
+ endpoint: str
15
+ raw_request: dict = None
16
+
17
17
 
18
+ class ImageGenerateResp(RespBase):
18
19
  meta: RequestParams
19
20
  files: List[Tuple[str, bytes]] = None
20
21
 
@@ -24,7 +24,7 @@ from ....utils.encode import tokens_to_b64
24
24
 
25
25
  class LLM(ApiBaseModel):
26
26
  """
27
- LLM Stream for /ai/generate-stream
27
+ LLM for /ai/generate
28
28
  """
29
29
  _endpoint: str = PrivateAttr("https://api.novelai.net")
30
30
  input: str = Field(..., description="Base64 encoded token text")
@@ -184,28 +184,28 @@ class LLM(ApiBaseModel):
184
184
  message = _msg.get("message", "Unknown error")
185
185
  if status_code == 400:
186
186
  raise APIError(
187
- "A validation error occured.",
187
+ f"A validation error occured. {message}",
188
188
  request=request_data, code=status_code, response=_msg
189
189
  )
190
190
 
191
191
  elif status_code == 401:
192
192
  raise APIError(
193
- "Access Token is incorrect.",
193
+ f"Access Token is incorrect. {message}",
194
194
  request=request_data, code=status_code, response=_msg
195
195
  )
196
196
  elif status_code == 402:
197
197
  raise APIError(
198
- "An active subscription is required to access this endpoint.",
198
+ f"An active subscription is required to access this endpoint. {message}",
199
199
  request=request_data, code=status_code, response=_msg
200
200
  )
201
201
  elif status_code == 409:
202
202
  raise APIError(
203
- "A conflict error occured.",
203
+ f"A conflict error occured. {message}",
204
204
  request=request_data, code=status_code, response=_msg
205
205
  )
206
206
  else:
207
207
  raise APIError(
208
- f"An unknown error occured.{response.status_code}",
208
+ f"An unknown error occured. {response.status_code} {message}",
209
209
  request=request_data, code=status_code, response=_msg
210
210
  )
211
211
  else:
@@ -1,6 +1,6 @@
1
1
  # Description: Enum class for TextLLMModel
2
2
  from enum import Enum
3
- from typing import List, Dict
3
+ from typing import List
4
4
 
5
5
 
6
6
  class TextLLMModel(Enum):
@@ -71,7 +71,7 @@ def generate_order(request_body: dict) -> List[int]:
71
71
  order_list = []
72
72
  for member in Order:
73
73
  key, order = member.value
74
- if key in request_body and request_body[key]:
74
+ if key in request_body and request_body[key] is None:
75
75
  order_list.append(order)
76
76
  order_list.sort() # ensures the order list is properly sorted according to the true order
77
77
  return order_list
@@ -28,7 +28,7 @@ from ._const import len_values, tempmin_value, sm_value, dyn_value, map_value
28
28
  from ._enum import Model, Sampler, NoiseSchedule, ControlNetModel, Action, UCPreset, INPAINTING_MODEL_LIST
29
29
  from ...schema import ApiBaseModel
30
30
  from ...._exceptions import APIError, AuthError, ConcurrentGenerationError, SessionHttpError
31
- from ...._response.ai.generate_image import ImageGenerateResp
31
+ from ...._response.ai.generate_image import ImageGenerateResp, RequestParams
32
32
  from ....credential import CredentialBase
33
33
  from ....utils import try_jsonfy
34
34
 
@@ -453,7 +453,7 @@ class GenerateImageInfer(ApiBaseModel):
453
453
  )
454
454
  per_sample = max(math.ceil(per_sample * strength), 2)
455
455
 
456
- if uncond_scale != 1.0:
456
+ if int(uncond_scale) != 1:
457
457
  per_sample = math.ceil(per_sample * 1.3)
458
458
 
459
459
  return per_sample * n_samples
@@ -755,7 +755,7 @@ class GenerateImageInfer(ApiBaseModel):
755
755
  data = zip_file.read(filename)
756
756
  unzip_content.append((filename, data))
757
757
  return ImageGenerateResp(
758
- meta=ImageGenerateResp.RequestParams(
758
+ meta=RequestParams(
759
759
  endpoint=self.base_url,
760
760
  raw_request=request_data,
761
761
  ),
@@ -93,6 +93,9 @@ class Model(Enum):
93
93
  NAI_DIFFUSION_3 = "nai-diffusion-3"
94
94
  NAI_DIFFUSION_3_INPAINTING = "nai-diffusion-3-inpainting"
95
95
 
96
+ NAI_DIFFUSION_FURRY_3 = "nai-diffusion-furry-3"
97
+ NAI_DIFFUSION_FURRY_3_INPAINTING = "nai-diffusion-furry-3-inpainting"
98
+
96
99
  NAI_DIFFUSION = "nai-diffusion"
97
100
  NAI_DIFFUSION_2 = "nai-diffusion-2"
98
101
  NAI_DIFFUSION_INPAINTING = "nai-diffusion-inpainting"
@@ -107,11 +110,13 @@ class Model(Enum):
107
110
  CUSTOM = "custom"
108
111
 
109
112
 
110
- INPAINTING_MODEL_LIST = [Model.NAI_DIFFUSION_3_INPAINTING,
111
- Model.NAI_DIFFUSION_INPAINTING,
112
- Model.SAFE_DIFFUSION_INPAINTING,
113
- Model.FURRY_DIFFUSION_INPAINTING
114
- ]
113
+ INPAINTING_MODEL_LIST = [
114
+ Model.NAI_DIFFUSION_3_INPAINTING,
115
+ Model.NAI_DIFFUSION_INPAINTING,
116
+ Model.SAFE_DIFFUSION_INPAINTING,
117
+ Model.FURRY_DIFFUSION_INPAINTING,
118
+ Model.NAI_DIFFUSION_FURRY_3_INPAINTING
119
+ ]
115
120
 
116
121
  PROMOTION = {
117
122
  "Stable Diffusion 1D44365E": Model.SAFE_DIFFUSION,
@@ -127,4 +132,7 @@ PROMOTION = {
127
132
  "Stable Diffusion XL B0BDF6C1": Model.NAI_DIFFUSION_3,
128
133
  "Stable Diffusion XL C1E1DE52": Model.NAI_DIFFUSION_3,
129
134
  "Stable Diffusion XL 8BA2AF87": Model.NAI_DIFFUSION_3,
135
+ "Stable Diffusion XL 4BE8C60C": Model.NAI_DIFFUSION_FURRY_3,
136
+ "Stable Diffusion XL C8704949": Model.NAI_DIFFUSION_FURRY_3,
137
+ "Stable Diffusion XL 9CC2F394": Model.NAI_DIFFUSION_FURRY_3,
130
138
  }
@@ -190,7 +190,6 @@ async def generate(
190
190
  generator = agent.request(session=session)
191
191
  async for data in generator:
192
192
  data: LLMStreamResp
193
- print(data) # 或者做其他需要的处理
194
193
  yield data.text # Yield data for streaming response
195
194
 
196
195
  return StreamingResponse(generator())
@@ -227,7 +226,11 @@ async def generate_voice(
227
226
  """
228
227
  生成图片
229
228
  :param current_token: Authorization
230
- :param req: GenerateImageInfer
229
+ :param text: str
230
+ :param voice: int
231
+ :param seed: Optional[str]
232
+ :param opus: bool
233
+ :param version: Union[Literal["v2", "v1"], str]
231
234
  :return:
232
235
  """
233
236
  try:
@@ -3,7 +3,7 @@ import base64
3
3
  import json
4
4
  from io import BytesIO
5
5
  from pathlib import Path
6
- from typing import Union
6
+ from typing import Union, Optional, List
7
7
 
8
8
  import numpy as np
9
9
  from PIL import Image
@@ -36,8 +36,10 @@ class ImageMetadata(BaseModel):
36
36
  hide_debug_overlay: bool = None
37
37
  noise_schedule: str = None
38
38
  legacy_v3_extend: bool = None
39
- reference_information_extracted: float = None
40
- reference_strength: float = None
39
+ reference_information_extracted: Optional[float] = None
40
+ reference_strength: Optional[float] = None
41
+ reference_strength_multiple: Optional[List[float]] = None
42
+ reference_information_extracted_multiple: Optional[List[float]] = None
41
43
  sampler: str = None
42
44
  controlnet_strength: float = None
43
45
  controlnet_model: Union[None, str] = None
@@ -58,6 +60,29 @@ class ImageMetadata(BaseModel):
58
60
  def negative_prompt(self):
59
61
  return self.uc
60
62
 
63
+ @property
64
+ def vibe_transfer_strength(self) -> List[float]:
65
+ """
66
+ Get the vibe transfer strength totally
67
+ :return: List[float]
68
+ """
69
+ if self.reference_strength_multiple:
70
+ return self.reference_strength_multiple
71
+ reference_strength = [] if self.reference_strength is None else [self.reference_strength]
72
+ return reference_strength
73
+
74
+ @property
75
+ def vibe_transfer_information(self) -> List[float]:
76
+ """
77
+ Get the vibe transfer information totally
78
+ :return: List[float]
79
+ """
80
+ if self.reference_information_extracted_multiple:
81
+ return self.reference_information_extracted_multiple
82
+ reference_information = [] if self.reference_information_extracted is None else [
83
+ self.reference_information_extracted]
84
+ return reference_information
85
+
61
86
  Title: str = "AI generated image"
62
87
  Software: str = "NovelAI"
63
88
  Source: str = None
@@ -2,12 +2,13 @@ import cv2 as cv
2
2
  import numpy as np
3
3
 
4
4
 
5
- def create_mask_from_sketch(original_img_bytes: bytes,
6
- sketch_img_bytes: bytes,
7
- min_block_size: int = 15,
8
- jagged_edges: bool = True,
9
- output_format: str = '.png'
10
- ) -> bytes:
5
+ def create_mask_from_sketch(
6
+ original_img_bytes: bytes,
7
+ sketch_img_bytes: bytes,
8
+ min_block_size: int = 15,
9
+ jagged_edges: bool = True,
10
+ output_format: str = '.png'
11
+ ) -> bytes:
11
12
  """
12
13
  Function to create a mask from original and sketch images input as bytes. Returns BytesIO object.
13
14
 
File without changes
File without changes