novelai-python 0.6.0__tar.gz → 0.7.0__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 (86) hide show
  1. {novelai_python-0.6.0 → novelai_python-0.7.0}/PKG-INFO +57 -41
  2. {novelai_python-0.6.0 → novelai_python-0.7.0}/README.md +56 -40
  3. {novelai_python-0.6.0 → novelai_python-0.7.0}/pyproject.toml +2 -1
  4. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_enum.py +1 -0
  5. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate/__init__.py +2 -1
  6. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate/_schema.py +1 -1
  7. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate_image/__init__.py +15 -10
  8. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tokenizer/__init__.py +15 -2
  9. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tool/image_metadata/__init__.py +160 -111
  10. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tool/image_metadata/lsb_extractor.py +41 -13
  11. novelai_python-0.7.0/src/novelai_python/tool/random_prompt/__init__.py +95 -0
  12. novelai_python-0.7.0/src/novelai_python/tool/random_prompt/generate_scene_composition.py +2960 -0
  13. novelai_python-0.7.0/src/novelai_python/tool/random_prompt/generate_scene_tags.py +2276 -0
  14. novelai_python-0.7.0/src/novelai_python/tool/random_prompt/generate_tags.py +2517 -0
  15. novelai_python-0.7.0/tests/test_random_prompt.py +61 -0
  16. novelai_python-0.7.0/tests/test_tokenizer.py +32 -0
  17. novelai_python-0.6.0/src/novelai_python/tool/image_metadata/_type.py +0 -21
  18. novelai_python-0.6.0/src/novelai_python/tool/random_prompt/__init__.py +0 -367
  19. novelai_python-0.6.0/src/novelai_python/tool/random_prompt/tag.py +0 -7542
  20. novelai_python-0.6.0/src/novelai_python/tool/random_prompt/tag_character.py +0 -270
  21. novelai_python-0.6.0/src/novelai_python/tool/random_prompt/tag_nsfw.py +0 -984
  22. novelai_python-0.6.0/tests/test_random_prompt.py +0 -70
  23. {novelai_python-0.6.0 → novelai_python-0.7.0}/LICENSE +0 -0
  24. {novelai_python-0.6.0 → novelai_python-0.7.0}/NOTICE.MD +0 -0
  25. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/__init__.py +0 -0
  26. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_exceptions.py +0 -0
  27. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/__init__.py +0 -0
  28. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/ai/__init__.py +0 -0
  29. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/ai/generate.py +0 -0
  30. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/ai/generate_image.py +0 -0
  31. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/ai/generate_stream.py +0 -0
  32. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/ai/generate_voice.py +0 -0
  33. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/ai/upscale.py +0 -0
  34. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/schema.py +0 -0
  35. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/user/__init__.py +0 -0
  36. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/user/information.py +0 -0
  37. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/user/login.py +0 -0
  38. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/_response/user/subscription.py +0 -0
  39. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/credential/ApiToken.py +0 -0
  40. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/credential/JwtToken.py +0 -0
  41. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/credential/UserAuth.py +0 -0
  42. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/credential/__init__.py +0 -0
  43. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/credential/_base.py +0 -0
  44. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/__init__.py +0 -0
  45. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/LICENSE +0 -0
  46. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/__init__.py +0 -0
  47. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/_const.py +0 -0
  48. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/_cost.py +0 -0
  49. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/_enum.py +0 -0
  50. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/augment_image/__init__.py +0 -0
  51. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/augment_image/_enum.py +0 -0
  52. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate/_const.py +0 -0
  53. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate/_enum.py +0 -0
  54. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate/themes.json +0 -0
  55. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate_image/schema.py +0 -0
  56. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate_image/suggest_tags.py +0 -0
  57. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate_stream.py +0 -0
  58. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate_voice/__init__.py +0 -0
  59. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/generate_voice/_enum.py +0 -0
  60. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/ai/upscale.py +0 -0
  61. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/schema.py +0 -0
  62. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/user/__init__.py +0 -0
  63. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/user/information.py +0 -0
  64. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/user/login.py +0 -0
  65. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/sdk/user/subscription.py +0 -0
  66. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/server.py +0 -0
  67. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tokenizer/clip_simple_tokenizer.py +0 -0
  68. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tokenizer/nerdstash_v1.model +0 -0
  69. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tokenizer/nerdstash_v2.model +0 -0
  70. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tokenizer/novelai.model +0 -0
  71. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tokenizer/novelai_v2.model +0 -0
  72. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tool/__init__.py +0 -0
  73. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tool/image_metadata/bch_utils.py +0 -0
  74. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tool/image_metadata/lsb_injector.py +0 -0
  75. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/tool/paint_mask/__init__.py +0 -0
  76. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/utils/__init__.py +0 -0
  77. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/utils/encode.py +0 -0
  78. {novelai_python-0.6.0 → novelai_python-0.7.0}/src/novelai_python/utils/useful.py +0 -0
  79. {novelai_python-0.6.0 → novelai_python-0.7.0}/tests/__init__.py +0 -0
  80. {novelai_python-0.6.0 → novelai_python-0.7.0}/tests/test_generate_voice.py +0 -0
  81. {novelai_python-0.6.0 → novelai_python-0.7.0}/tests/test_server.py +0 -0
  82. {novelai_python-0.6.0 → novelai_python-0.7.0}/tests/test_server_run.py +0 -0
  83. {novelai_python-0.6.0 → novelai_python-0.7.0}/tests/test_upscale.py +0 -0
  84. {novelai_python-0.6.0 → novelai_python-0.7.0}/tests/test_user_information.py +0 -0
  85. {novelai_python-0.6.0 → novelai_python-0.7.0}/tests/test_user_login.py +0 -0
  86. {novelai_python-0.6.0 → novelai_python-0.7.0}/tests/test_user_subscription.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: novelai-python
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: NovelAI Python Binding With Pydantic
5
5
  Author-Email: sudoskys <coldlando@hotmail.com>
6
6
  License: Apache License 2.0
@@ -41,47 +41,30 @@ Description-Content-Type: text/markdown
41
41
  ---
42
42
 
43
43
  [![PyPI version](https://badge.fury.io/py/novelai-python.svg)](https://badge.fury.io/py/novelai-python)
44
- [![Downloads](https://static.pepy.tech/badge/novelai_python)](https://static.pepy.tech/project/novelai_python)
44
+ [![Downloads](https://pepy.tech/badge/novelai_python)](https://pepy.tech/project/novelai_python)
45
45
 
46
46
  ✨ NovelAI api python sdk with Pydantic, modern and user-friendly.
47
47
 
48
- The goal of this repository is to use Pydantic to build legitimate requests to access the NovelAI API service.
48
+ The goal of this repository is to use Pydantic to build legitimate requests to access
49
+ the [NovelAI API service](https://api.novelai.net/docs).
49
50
 
50
51
  > Python >= 3.9 is required.
51
52
 
52
- ### Roadmap 🚧
53
+ ### 📰 News
53
54
 
54
- - [x] tool.random_prompt
55
- - [x] tool.paint_mask
56
- - [x] tool.image_metadata
57
- - [x] tokenizer
58
- - [x] /ai/generate-image
59
- - [x] /user/subscription
60
- - [x] /user/login
61
- - [x] /user/information
62
- - [x] /ai/upscale
63
- - [x] /ai/generate-image/suggest-tags
64
- - [x] /ai/generate-voice
65
- - [x] /ai/generate-stream
66
- - [x] /ai/generate
67
- - [x] /ai/augment-image
68
- - [ ] /ai/annotate-image
69
- - [ ] /ai/classify
70
- - [ ] /ai/generate-prompt
71
-
72
- > GenerateImageInfer.calculate_cost is correct in most cases, but please request account information to get accurate
73
- > consumption information.
74
-
75
- > This repo is maintained by me personally now. If you have any questions, please feel free to open an issue.
55
+ - [Image Generation Model Release — NovelAI Anime Diffusion V4 Curated Preview (EN)](https://blog.novelai.net/release-novelai-anime-diffusion-v4-curated-preview-en-ca4b0b11e671)
56
+ - [Tutorial: Creating Consistent Characters with NovelAI Diffusion Anime [Female]](https://blog.novelai.net/tutorial-en-creating-consistent-characters-with-novelai-diffusion-anime-female-538b4b678a4e)
76
57
 
77
- ### Usage 🖥️
58
+ ### 📦 Usage
78
59
 
79
60
  ```shell
80
61
  pip -U install novelai-python
81
62
  ```
82
63
 
83
- More examples can be found in the [playground](https://github.com/LlmKira/novelai-python/tree/main/playground)
84
- directory, read code as documentation.
64
+ All API users must adhere to the NovelAI Terms of Service: https://novelai.net/terms.
65
+
66
+ **More examples can be found in the [playground](https://github.com/LlmKira/novelai-python/tree/main/playground)
67
+ directory, read code as documentation.**
85
68
 
86
69
  ```python
87
70
  import asyncio
@@ -96,6 +79,7 @@ from novelai_python.sdk.ai.generate_image.schema import PositionMap
96
79
 
97
80
  load_dotenv()
98
81
  session = ApiCredential(api_token=SecretStr(os.getenv("NOVELAI_JWT"))) # pst-***
82
+ # For security reasons, storing user credentials in plaintext is strongly discouraged.
99
83
 
100
84
  prompt = "1girl, year 2023,dynamic angle, best quality, amazing quality, very aesthetic, absurdres"
101
85
 
@@ -126,7 +110,7 @@ async def main():
126
110
  )
127
111
  cost = gen.calculate_cost(is_opus=True)
128
112
  print(f"charge: {cost} if you are vip3")
129
- resp = gen.request(session=session)
113
+ resp = await gen.request(session=session)
130
114
  resp: ImageGenerateResp
131
115
  print(resp.meta)
132
116
  file = resp.files[0]
@@ -139,7 +123,7 @@ loop.run_until_complete(main())
139
123
 
140
124
  ```
141
125
 
142
- #### LLM
126
+ #### 📦 LLM
143
127
 
144
128
  ```python
145
129
  import asyncio
@@ -190,29 +174,38 @@ loop = asyncio.get_event_loop()
190
174
  loop.run_until_complete(chat("Hello"))
191
175
  ```
192
176
 
193
- #### Random Prompt
177
+ #### 📦 Random Prompt
194
178
 
195
179
  ```python
196
180
  from novelai_python.tool.random_prompt import RandomPromptGenerator
197
181
 
198
- prompt = RandomPromptGenerator(nsfw_enabled=False).random_prompt()
199
- print(prompt)
182
+ generator = RandomPromptGenerator()
183
+ for i in range(10):
184
+ print(generator.generate_common_tags(nsfw=False))
185
+ print(generator.generate_scene_tags())
186
+ print(generator.generate_scene_composition())
187
+ print(generator.get_holiday_themed_tags())
200
188
  ```
201
189
 
202
- #### Run A Server
190
+ #### 📦 Run A Server
203
191
 
204
192
  ```shell
205
193
  pip install novelai_python
206
194
  python3 -m novelai_python.server -h '127.0.0.1' -p 7888
207
195
  ```
208
196
 
209
- #### Tokenizer
197
+ #### 📦 Tokenizer
210
198
 
211
199
  ```python
212
- from novelai_python._enum import get_tokenizer_model, TextLLMModel
200
+ from novelai_python._enum import get_tokenizer_model, TextLLMModel, TextTokenizerGroup
213
201
  from novelai_python.tokenizer import NaiTokenizer
214
202
 
203
+ # Through llm model name to get the tokenizer
215
204
  tokenizer_package = NaiTokenizer(get_tokenizer_model(TextLLMModel.ERATO))
205
+ # Directly use the tokenizer
206
+ clip_tokenizer = NaiTokenizer(TextTokenizerGroup.CLIP)
207
+
208
+ # Tokenize a text
216
209
  t_text = "a fox jumped over the lazy dog"
217
210
  encode_tokens = tokenizer_package.encode(t_text)
218
211
  print(tokenizer_package.tokenize_text(t_text))
@@ -221,7 +214,32 @@ print(tokenizer_package.decode(tokenizer_package.encode(t_text)))
221
214
 
222
215
  ```
223
216
 
224
- ## About Nsfw 🚫
217
+ ### 🔨 Roadmap
218
+
219
+ - [x] tool.random_prompt
220
+ - [x] tool.paint_mask
221
+ - [x] tool.image_metadata
222
+ - [x] tokenizer
223
+ - [x] /ai/generate-image
224
+ - [x] /user/subscription
225
+ - [x] /user/login
226
+ - [x] /user/information
227
+ - [x] /ai/upscale
228
+ - [x] /ai/generate-image/suggest-tags
229
+ - [x] /ai/generate-voice
230
+ - [x] /ai/generate-stream
231
+ - [x] /ai/generate
232
+ - [x] /ai/augment-image
233
+ - [ ] /ai/annotate-image
234
+ - [ ] /ai/classify
235
+ - [ ] /ai/generate-prompt
236
+
237
+ > GenerateImageInfer.calculate_cost is correct in most cases, but please request account information to get accurate
238
+ > consumption information.
239
+
240
+ > This repo is maintained by me personally now. If you have any questions, please feel free to open an issue.
241
+
242
+ ## 🚫 About Nsfw
225
243
 
226
244
  You might need some solutions for identifying NSFW content and adding a mosaic to prevent operational mishaps.
227
245
 
@@ -229,9 +247,7 @@ https://dghs-imgutils.deepghs.org/main/api_doc/detect/nudenet.html
229
247
 
230
248
  https://dghs-imgutils.deepghs.org/main/api_doc/operate/censor.html
231
249
 
232
- ## Acknowledgements 🙏
233
-
234
- [BackEnd](https://api.novelai.net/docs)
250
+ ## 🙏 Acknowledgements
235
251
 
236
252
  [novelai-api](https://github.com/Aedial/novelai-api)
237
253
 
@@ -3,47 +3,30 @@
3
3
  ---
4
4
 
5
5
  [![PyPI version](https://badge.fury.io/py/novelai-python.svg)](https://badge.fury.io/py/novelai-python)
6
- [![Downloads](https://static.pepy.tech/badge/novelai_python)](https://static.pepy.tech/project/novelai_python)
6
+ [![Downloads](https://pepy.tech/badge/novelai_python)](https://pepy.tech/project/novelai_python)
7
7
 
8
8
  ✨ NovelAI api python sdk with Pydantic, modern and user-friendly.
9
9
 
10
- The goal of this repository is to use Pydantic to build legitimate requests to access the NovelAI API service.
10
+ The goal of this repository is to use Pydantic to build legitimate requests to access
11
+ the [NovelAI API service](https://api.novelai.net/docs).
11
12
 
12
13
  > Python >= 3.9 is required.
13
14
 
14
- ### Roadmap 🚧
15
+ ### 📰 News
15
16
 
16
- - [x] tool.random_prompt
17
- - [x] tool.paint_mask
18
- - [x] tool.image_metadata
19
- - [x] tokenizer
20
- - [x] /ai/generate-image
21
- - [x] /user/subscription
22
- - [x] /user/login
23
- - [x] /user/information
24
- - [x] /ai/upscale
25
- - [x] /ai/generate-image/suggest-tags
26
- - [x] /ai/generate-voice
27
- - [x] /ai/generate-stream
28
- - [x] /ai/generate
29
- - [x] /ai/augment-image
30
- - [ ] /ai/annotate-image
31
- - [ ] /ai/classify
32
- - [ ] /ai/generate-prompt
33
-
34
- > GenerateImageInfer.calculate_cost is correct in most cases, but please request account information to get accurate
35
- > consumption information.
36
-
37
- > This repo is maintained by me personally now. If you have any questions, please feel free to open an issue.
17
+ - [Image Generation Model Release — NovelAI Anime Diffusion V4 Curated Preview (EN)](https://blog.novelai.net/release-novelai-anime-diffusion-v4-curated-preview-en-ca4b0b11e671)
18
+ - [Tutorial: Creating Consistent Characters with NovelAI Diffusion Anime [Female]](https://blog.novelai.net/tutorial-en-creating-consistent-characters-with-novelai-diffusion-anime-female-538b4b678a4e)
38
19
 
39
- ### Usage 🖥️
20
+ ### 📦 Usage
40
21
 
41
22
  ```shell
42
23
  pip -U install novelai-python
43
24
  ```
44
25
 
45
- More examples can be found in the [playground](https://github.com/LlmKira/novelai-python/tree/main/playground)
46
- directory, read code as documentation.
26
+ All API users must adhere to the NovelAI Terms of Service: https://novelai.net/terms.
27
+
28
+ **More examples can be found in the [playground](https://github.com/LlmKira/novelai-python/tree/main/playground)
29
+ directory, read code as documentation.**
47
30
 
48
31
  ```python
49
32
  import asyncio
@@ -58,6 +41,7 @@ from novelai_python.sdk.ai.generate_image.schema import PositionMap
58
41
 
59
42
  load_dotenv()
60
43
  session = ApiCredential(api_token=SecretStr(os.getenv("NOVELAI_JWT"))) # pst-***
44
+ # For security reasons, storing user credentials in plaintext is strongly discouraged.
61
45
 
62
46
  prompt = "1girl, year 2023,dynamic angle, best quality, amazing quality, very aesthetic, absurdres"
63
47
 
@@ -88,7 +72,7 @@ async def main():
88
72
  )
89
73
  cost = gen.calculate_cost(is_opus=True)
90
74
  print(f"charge: {cost} if you are vip3")
91
- resp = gen.request(session=session)
75
+ resp = await gen.request(session=session)
92
76
  resp: ImageGenerateResp
93
77
  print(resp.meta)
94
78
  file = resp.files[0]
@@ -101,7 +85,7 @@ loop.run_until_complete(main())
101
85
 
102
86
  ```
103
87
 
104
- #### LLM
88
+ #### 📦 LLM
105
89
 
106
90
  ```python
107
91
  import asyncio
@@ -152,29 +136,38 @@ loop = asyncio.get_event_loop()
152
136
  loop.run_until_complete(chat("Hello"))
153
137
  ```
154
138
 
155
- #### Random Prompt
139
+ #### 📦 Random Prompt
156
140
 
157
141
  ```python
158
142
  from novelai_python.tool.random_prompt import RandomPromptGenerator
159
143
 
160
- prompt = RandomPromptGenerator(nsfw_enabled=False).random_prompt()
161
- print(prompt)
144
+ generator = RandomPromptGenerator()
145
+ for i in range(10):
146
+ print(generator.generate_common_tags(nsfw=False))
147
+ print(generator.generate_scene_tags())
148
+ print(generator.generate_scene_composition())
149
+ print(generator.get_holiday_themed_tags())
162
150
  ```
163
151
 
164
- #### Run A Server
152
+ #### 📦 Run A Server
165
153
 
166
154
  ```shell
167
155
  pip install novelai_python
168
156
  python3 -m novelai_python.server -h '127.0.0.1' -p 7888
169
157
  ```
170
158
 
171
- #### Tokenizer
159
+ #### 📦 Tokenizer
172
160
 
173
161
  ```python
174
- from novelai_python._enum import get_tokenizer_model, TextLLMModel
162
+ from novelai_python._enum import get_tokenizer_model, TextLLMModel, TextTokenizerGroup
175
163
  from novelai_python.tokenizer import NaiTokenizer
176
164
 
165
+ # Through llm model name to get the tokenizer
177
166
  tokenizer_package = NaiTokenizer(get_tokenizer_model(TextLLMModel.ERATO))
167
+ # Directly use the tokenizer
168
+ clip_tokenizer = NaiTokenizer(TextTokenizerGroup.CLIP)
169
+
170
+ # Tokenize a text
178
171
  t_text = "a fox jumped over the lazy dog"
179
172
  encode_tokens = tokenizer_package.encode(t_text)
180
173
  print(tokenizer_package.tokenize_text(t_text))
@@ -183,7 +176,32 @@ print(tokenizer_package.decode(tokenizer_package.encode(t_text)))
183
176
 
184
177
  ```
185
178
 
186
- ## About Nsfw 🚫
179
+ ### 🔨 Roadmap
180
+
181
+ - [x] tool.random_prompt
182
+ - [x] tool.paint_mask
183
+ - [x] tool.image_metadata
184
+ - [x] tokenizer
185
+ - [x] /ai/generate-image
186
+ - [x] /user/subscription
187
+ - [x] /user/login
188
+ - [x] /user/information
189
+ - [x] /ai/upscale
190
+ - [x] /ai/generate-image/suggest-tags
191
+ - [x] /ai/generate-voice
192
+ - [x] /ai/generate-stream
193
+ - [x] /ai/generate
194
+ - [x] /ai/augment-image
195
+ - [ ] /ai/annotate-image
196
+ - [ ] /ai/classify
197
+ - [ ] /ai/generate-prompt
198
+
199
+ > GenerateImageInfer.calculate_cost is correct in most cases, but please request account information to get accurate
200
+ > consumption information.
201
+
202
+ > This repo is maintained by me personally now. If you have any questions, please feel free to open an issue.
203
+
204
+ ## 🚫 About Nsfw
187
205
 
188
206
  You might need some solutions for identifying NSFW content and adding a mosaic to prevent operational mishaps.
189
207
 
@@ -191,9 +209,7 @@ https://dghs-imgutils.deepghs.org/main/api_doc/detect/nudenet.html
191
209
 
192
210
  https://dghs-imgutils.deepghs.org/main/api_doc/operate/censor.html
193
211
 
194
- ## Acknowledgements 🙏
195
-
196
- [BackEnd](https://api.novelai.net/docs)
212
+ ## 🙏 Acknowledgements
197
213
 
198
214
  [novelai-api](https://github.com/Aedial/novelai-api)
199
215
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "novelai-python"
3
- version = "0.6.0"
3
+ version = "0.7.0"
4
4
  description = "NovelAI Python Binding With Pydantic"
5
5
  authors = [
6
6
  { name = "sudoskys", email = "coldlando@hotmail.com" },
@@ -59,4 +59,5 @@ distribution = true
59
59
  [tool.pdm.dev-dependencies]
60
60
  dev = [
61
61
  "pre-commit>=3.5.0",
62
+ "wasmtime>=28.0.0",
62
63
  ]
@@ -40,6 +40,7 @@ class TextTokenizerGroup(object):
40
40
  LLAMA3 = "llama3_tokenizer.def"
41
41
  GPT2 = "gpt2_tokenizer.def"
42
42
  CLIP = "clip_tokenizer.def"
43
+ T5 = "t5_tokenizer.def"
43
44
 
44
45
 
45
46
  TextLLMModelTypeAlias = Union[TextLLMModel, str]
@@ -341,7 +341,8 @@ class LLM(ApiBaseModel):
341
341
  override_headers: Optional[dict] = None
342
342
  ) -> LLMResp:
343
343
  """
344
- 生成图片
344
+ Generate text using NovelAI's large language models. 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.
345
+
345
346
  :param override_headers:
346
347
  :param session: session
347
348
  :return: LLMStreamResp
@@ -115,7 +115,7 @@ class LLMGenerationParams(BaseModel):
115
115
  repetition_penalty_slope: Optional[Union[float, int]] = Field(default=None, ge=0, allow_inf_nan=False)
116
116
 
117
117
  eos_token_id: int = None
118
- bad_words_ids: List[List[int]] = None
118
+ bad_words_ids: Optional[List[List[int]]] = None
119
119
  logit_bias_groups: Optional[List[LogitBiasGroup]] = Field(default_factory=list)
120
120
 
121
121
  repetition_penalty_frequency: Optional[Union[float, int]] = Field(default=None, allow_inf_nan=False)
@@ -7,7 +7,6 @@ import json
7
7
  import math
8
8
  import random
9
9
  from copy import deepcopy
10
- from dataclasses import field
11
10
  from io import BytesIO
12
11
  from typing import Optional, Union, Tuple, List
13
12
  from urllib.parse import urlparse
@@ -28,7 +27,7 @@ from novelai_python.sdk.ai._cost import CostCalculator
28
27
  from novelai_python.sdk.ai._enum import Model, Sampler, NoiseSchedule, ControlNetModel, Action, UCPreset, \
29
28
  INPAINTING_MODEL_LIST, get_default_uc_preset, \
30
29
  ModelTypeAlias, UCPresetTypeAlias, get_default_noise_schedule, get_supported_noise_schedule, \
31
- get_model_group, ModelGroups, get_supported_params, get_modifiers
30
+ get_model_group, ModelGroups, get_supported_params, get_modifiers, ImageBytesTypeAlias
32
31
  from .schema import Character, V4Prompt, V4NegativePrompt
33
32
  from ...schema import ApiBaseModel
34
33
  from ...._exceptions import APIError, AuthError, ConcurrentGenerationError, SessionHttpError
@@ -79,7 +78,7 @@ class Params(BaseModel):
79
78
  """Noise Schedule"""
80
79
  legacy_v3_extend: Optional[bool] = False
81
80
  """Legacy V3 Extend"""
82
- mask: Union[bytes, str] = None
81
+ mask: ImageBytesTypeAlias = None
83
82
  """Mask for Inpainting"""
84
83
  seed: int = Field(
85
84
  default_factory=lambda: random.randint(0, 4294967295 - 7),
@@ -87,13 +86,13 @@ class Params(BaseModel):
87
86
  le=4294967295 - 7,
88
87
  )
89
88
  """Seed"""
90
- image: Union[bytes, str] = None
89
+ image: ImageBytesTypeAlias = None
91
90
  """Image for img2img"""
92
91
  negative_prompt: Optional[str] = ''
93
92
  """Negative Prompt"""
94
- reference_image_multiple: Optional[List[Union[str, bytes]]] = field(default_factory=list)
93
+ reference_image_multiple: Optional[List[Union[str, bytes]]] = Field(default_factory=list)
95
94
  """Reference Image For Vibe Mode"""
96
- reference_information_extracted_multiple: Optional[List[float]] = field(default_factory=list)
95
+ reference_information_extracted_multiple: Optional[List[float]] = Field(default_factory=list)
97
96
  """Reference Information Extracted For Vibe Mode"""
98
97
  reference_strength_multiple: Optional[List[float]] = Field(
99
98
  default=list,
@@ -113,7 +112,7 @@ class Params(BaseModel):
113
112
  """
114
113
  use_coords: bool = Field(True, description="Use Coordinates")
115
114
  """Use Coordinates"""
116
- characterPrompts: List[Character] = field(default_factory=list)
115
+ characterPrompts: List[Character] = Field(default_factory=list)
117
116
  """Character Prompts"""
118
117
 
119
118
  v4_prompt: Optional[V4Prompt] = Field(None, description="V4 Prompt")
@@ -136,6 +135,12 @@ class Params(BaseModel):
136
135
  uncond_scale: Optional[float] = Field(None, ge=0, le=1.5, multiple_of=0.05)
137
136
  """Undesired Content Strength"""
138
137
 
138
+ @model_validator(mode="after")
139
+ def v_character(self):
140
+ if len(self.characterPrompts) > 6:
141
+ raise ValueError("Too many character given")
142
+ return self
143
+
139
144
  @field_validator('uncond_scale')
140
145
  def v_uncond_scale(cls, v: float):
141
146
  """
@@ -684,10 +689,9 @@ class GenerateImageInfer(ApiBaseModel):
684
689
 
685
690
  If you need to define more parameters, you should initialize the Param class yourself.
686
691
 
687
- :param controlnet_strength:
688
692
  :param strength:
689
693
  :param image:
690
- :param noise: For img2img
694
+ :param noise: For image to image
691
695
  :param extra_noise_seed: Get extra_noise_seed
692
696
  :param reference_information_extracted_multiple:
693
697
  :param reference_strength_multiple:
@@ -887,7 +891,8 @@ class GenerateImageInfer(ApiBaseModel):
887
891
  override_headers: Optional[dict] = None,
888
892
  ) -> ImageGenerateResp:
889
893
  """
890
- 生成图片
894
+ Generate images using NovelAI's diffusion models. 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
+
891
896
  :param override_headers: the headers to override
892
897
  :param session: session
893
898
  :return:
@@ -1,5 +1,6 @@
1
1
  import gzip
2
2
  import io
3
+ import json
3
4
  import pathlib
4
5
  import zlib
5
6
  from typing import Dict, List, Optional
@@ -56,6 +57,14 @@ class LLMTokenizerSetting(TokenizerSetting):
56
57
  return self
57
58
 
58
59
 
60
+ def is_clip_model(model_name: str) -> bool:
61
+ return model_name.lower().startswith("clip_tokenizer")
62
+
63
+
64
+ def is_t5_model(model_name: str) -> bool:
65
+ return model_name.lower().startswith("t5_tokenizer")
66
+
67
+
59
68
  class NaiTokenizer:
60
69
  def __init__(self,
61
70
  model: str,
@@ -129,8 +138,10 @@ class NaiTokenizer:
129
138
  decoded_str = self._read_compressed_def(model_bytes)
130
139
  repaired_data = repair_json(decoded_str, return_objects=True)
131
140
  try:
132
- if "clip" in self.model_full_name.lower():
141
+ if is_clip_model(self.model_full_name):
133
142
  self.tokenizer_setting = ClipTokenizerSetting.model_validate(repaired_data)
143
+ elif is_t5_model(self.model_full_name):
144
+ self.tokenizer_setting = json.dumps(repaired_data)
134
145
  else:
135
146
  self.tokenizer_setting = LLMTokenizerSetting.model_validate(repaired_data)
136
147
  except Exception as e:
@@ -140,8 +151,10 @@ class NaiTokenizer:
140
151
  )
141
152
 
142
153
  def _create_tokenizer(self):
143
- if "clip" in self.model_full_name.lower():
154
+ if is_clip_model(self.model_full_name):
144
155
  self._create_clip_tokenizer()
156
+ elif is_t5_model(self.model_full_name):
157
+ self.tokenizer = Tokenizer.from_str(self.tokenizer_setting)
145
158
  else:
146
159
  self._create_bpe_tokenizer()
147
160