novelai-python 0.5.3__tar.gz → 0.6.1__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 (81) hide show
  1. {novelai_python-0.5.3 → novelai_python-0.6.1}/PKG-INFO +67 -37
  2. {novelai_python-0.5.3 → novelai_python-0.6.1}/README.md +65 -35
  3. {novelai_python-0.5.3 → novelai_python-0.6.1}/pyproject.toml +2 -2
  4. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/__init__.py +1 -1
  5. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/__init__.py +1 -1
  6. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/generate_image.py +1 -1
  7. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/upscale.py +1 -1
  8. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/schema.py +1 -1
  9. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/user/__init__.py +1 -1
  10. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/user/information.py +1 -1
  11. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/user/login.py +1 -1
  12. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/user/subscription.py +1 -1
  13. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/credential/ApiToken.py +3 -3
  14. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/credential/JwtToken.py +3 -3
  15. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/credential/UserAuth.py +8 -8
  16. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/credential/__init__.py +1 -1
  17. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/credential/_base.py +1 -1
  18. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/__init__.py +1 -1
  19. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/__init__.py +1 -1
  20. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/_cost.py +7 -7
  21. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/_enum.py +158 -2
  22. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/augment_image/__init__.py +3 -3
  23. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate/__init__.py +1 -0
  24. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate/_schema.py +17 -15
  25. novelai_python-0.6.1/src/novelai_python/sdk/ai/generate_image/__init__.py +994 -0
  26. novelai_python-0.6.1/src/novelai_python/sdk/ai/generate_image/schema.py +129 -0
  27. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate_image/suggest_tags.py +1 -1
  28. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/upscale.py +0 -1
  29. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/schema.py +1 -1
  30. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/user/__init__.py +1 -1
  31. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/user/information.py +1 -1
  32. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/user/login.py +1 -1
  33. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/user/subscription.py +1 -1
  34. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/clip_simple_tokenizer.py +3 -2
  35. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/random_prompt/tag.py +1 -1
  36. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/random_prompt/tag_character.py +1 -1
  37. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/random_prompt/tag_nsfw.py +1 -1
  38. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/utils/__init__.py +1 -1
  39. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/utils/useful.py +1 -1
  40. {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_random_prompt.py +1 -1
  41. {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_server.py +7 -2
  42. {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_server_run.py +1 -1
  43. {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_upscale.py +2 -2
  44. {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_user_information.py +1 -1
  45. {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_user_login.py +1 -1
  46. {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_user_subscription.py +1 -1
  47. novelai_python-0.5.3/src/novelai_python/sdk/ai/generate_image/__init__.py +0 -741
  48. {novelai_python-0.5.3 → novelai_python-0.6.1}/LICENSE +0 -0
  49. {novelai_python-0.5.3 → novelai_python-0.6.1}/NOTICE.MD +0 -0
  50. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/__init__.py +0 -0
  51. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_enum.py +0 -0
  52. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_exceptions.py +0 -0
  53. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/generate.py +0 -0
  54. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/generate_stream.py +0 -0
  55. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/generate_voice.py +0 -0
  56. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/LICENSE +0 -0
  57. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/_const.py +0 -0
  58. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/augment_image/_enum.py +0 -0
  59. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate/_const.py +0 -0
  60. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate/_enum.py +0 -0
  61. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate/themes.json +0 -0
  62. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate_stream.py +0 -0
  63. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate_voice/__init__.py +0 -0
  64. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate_voice/_enum.py +0 -0
  65. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/server.py +0 -0
  66. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/__init__.py +0 -0
  67. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/nerdstash_v1.model +0 -0
  68. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/nerdstash_v2.model +0 -0
  69. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/novelai.model +0 -0
  70. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/novelai_v2.model +0 -0
  71. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/__init__.py +0 -0
  72. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/image_metadata/__init__.py +0 -0
  73. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/image_metadata/_type.py +0 -0
  74. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/image_metadata/bch_utils.py +0 -0
  75. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/image_metadata/lsb_extractor.py +0 -0
  76. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/image_metadata/lsb_injector.py +0 -0
  77. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/paint_mask/__init__.py +0 -0
  78. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/random_prompt/__init__.py +0 -0
  79. {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/utils/encode.py +0 -0
  80. {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/__init__.py +0 -0
  81. {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_generate_voice.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: novelai-python
3
- Version: 0.5.3
3
+ Version: 0.6.1
4
4
  Summary: NovelAI Python Binding With Pydantic
5
5
  Author-Email: sudoskys <coldlando@hotmail.com>
6
6
  License: Apache License 2.0
@@ -10,7 +10,7 @@ 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
13
- Requires-Dist: pydantic>=2.5.3
13
+ Requires-Dist: pydantic>=2.9.0
14
14
  Requires-Dist: httpx>=0.26.0
15
15
  Requires-Dist: shortuuid>=1.0.11
16
16
  Requires-Dist: Pillow>=10.2.0
@@ -49,39 +49,19 @@ The goal of this repository is to use Pydantic to build legitimate requests to a
49
49
 
50
50
  > Python >= 3.9 is required.
51
51
 
52
- ### Roadmap 🚧
52
+ ### 📰 News
53
53
 
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.
54
+ - [Image Generation Model Release — NovelAI Anime Diffusion V4 Curated Preview (EN)](https://blog.novelai.net/release-novelai-anime-diffusion-v4-curated-preview-en-ca4b0b11e671)
55
+ - [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
56
 
77
- ### Usage 🖥️
57
+ ### 📦 Usage
78
58
 
79
59
  ```shell
80
60
  pip -U install novelai-python
81
61
  ```
82
62
 
83
- More examples can be found in the [playground](https://github.com/LlmKira/novelai-python/tree/main/playground)
84
- directory, read code as documentation.
63
+ **More examples can be found in the [playground](https://github.com/LlmKira/novelai-python/tree/main/playground)
64
+ directory, read code as documentation.**
85
65
 
86
66
  ```python
87
67
  import asyncio
@@ -91,17 +71,42 @@ from dotenv import load_dotenv
91
71
  from pydantic import SecretStr
92
72
 
93
73
  from novelai_python import GenerateImageInfer, ImageGenerateResp, ApiCredential
74
+ from novelai_python.sdk.ai.generate_image import Model, Character, Sampler, UCPreset
75
+ from novelai_python.sdk.ai.generate_image.schema import PositionMap
94
76
 
95
77
  load_dotenv()
96
- enhance = "year 2023,dynamic angle, best quality, amazing quality, very aesthetic, absurdres"
97
78
  session = ApiCredential(api_token=SecretStr(os.getenv("NOVELAI_JWT"))) # pst-***
98
79
 
80
+ prompt = "1girl, year 2023,dynamic angle, best quality, amazing quality, very aesthetic, absurdres"
81
+
99
82
 
100
83
  async def main():
101
- gen = await GenerateImageInfer.build(prompt=f"1girl,{enhance}")
84
+ gen = GenerateImageInfer.build_generate(
85
+ prompt=prompt,
86
+ model=Model.NAI_DIFFUSION_4_CURATED_PREVIEW,
87
+ character_prompts=[
88
+ Character(
89
+ prompt="1girl",
90
+ uc="red hair",
91
+ center=PositionMap.AUTO
92
+ ),
93
+ Character(
94
+ prompt="1boy",
95
+ center=PositionMap.E5
96
+ )
97
+ ],
98
+ sampler=Sampler.K_EULER_ANCESTRAL,
99
+ ucPreset=UCPreset.TYPE0,
100
+ # Recommended, using preset negative_prompt depends on selected model
101
+ qualitySuffix=True,
102
+ qualityToggle=True,
103
+ decrisp_mode=False,
104
+ variety_boost=True,
105
+ # Checkbox in novelai.net
106
+ )
102
107
  cost = gen.calculate_cost(is_opus=True)
103
108
  print(f"charge: {cost} if you are vip3")
104
- resp = gen.request(session=session)
109
+ resp = await gen.request(session=session)
105
110
  resp: ImageGenerateResp
106
111
  print(resp.meta)
107
112
  file = resp.files[0]
@@ -114,7 +119,7 @@ loop.run_until_complete(main())
114
119
 
115
120
  ```
116
121
 
117
- #### LLM
122
+ #### 📦 LLM
118
123
 
119
124
  ```python
120
125
  import asyncio
@@ -165,7 +170,7 @@ loop = asyncio.get_event_loop()
165
170
  loop.run_until_complete(chat("Hello"))
166
171
  ```
167
172
 
168
- #### Random Prompt
173
+ #### 📦 Random Prompt
169
174
 
170
175
  ```python
171
176
  from novelai_python.tool.random_prompt import RandomPromptGenerator
@@ -174,14 +179,14 @@ prompt = RandomPromptGenerator(nsfw_enabled=False).random_prompt()
174
179
  print(prompt)
175
180
  ```
176
181
 
177
- #### Run A Server
182
+ #### 📦 Run A Server
178
183
 
179
184
  ```shell
180
185
  pip install novelai_python
181
186
  python3 -m novelai_python.server -h '127.0.0.1' -p 7888
182
187
  ```
183
188
 
184
- #### Tokenizer
189
+ #### 📦 Tokenizer
185
190
 
186
191
  ```python
187
192
  from novelai_python._enum import get_tokenizer_model, TextLLMModel
@@ -196,7 +201,32 @@ print(tokenizer_package.decode(tokenizer_package.encode(t_text)))
196
201
 
197
202
  ```
198
203
 
199
- ## About Nsfw 🚫
204
+ ### 🔨 Roadmap
205
+
206
+ - [x] tool.random_prompt
207
+ - [x] tool.paint_mask
208
+ - [x] tool.image_metadata
209
+ - [x] tokenizer
210
+ - [x] /ai/generate-image
211
+ - [x] /user/subscription
212
+ - [x] /user/login
213
+ - [x] /user/information
214
+ - [x] /ai/upscale
215
+ - [x] /ai/generate-image/suggest-tags
216
+ - [x] /ai/generate-voice
217
+ - [x] /ai/generate-stream
218
+ - [x] /ai/generate
219
+ - [x] /ai/augment-image
220
+ - [ ] /ai/annotate-image
221
+ - [ ] /ai/classify
222
+ - [ ] /ai/generate-prompt
223
+
224
+ > GenerateImageInfer.calculate_cost is correct in most cases, but please request account information to get accurate
225
+ > consumption information.
226
+
227
+ > This repo is maintained by me personally now. If you have any questions, please feel free to open an issue.
228
+
229
+ ## 🚫 About Nsfw
200
230
 
201
231
  You might need some solutions for identifying NSFW content and adding a mosaic to prevent operational mishaps.
202
232
 
@@ -204,7 +234,7 @@ https://dghs-imgutils.deepghs.org/main/api_doc/detect/nudenet.html
204
234
 
205
235
  https://dghs-imgutils.deepghs.org/main/api_doc/operate/censor.html
206
236
 
207
- ## Acknowledgements 🙏
237
+ ## 🙏 Acknowledgements
208
238
 
209
239
  [BackEnd](https://api.novelai.net/docs)
210
240
 
@@ -11,39 +11,19 @@ The goal of this repository is to use Pydantic to build legitimate requests to a
11
11
 
12
12
  > Python >= 3.9 is required.
13
13
 
14
- ### Roadmap 🚧
14
+ ### 📰 News
15
15
 
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.
16
+ - [Image Generation Model Release — NovelAI Anime Diffusion V4 Curated Preview (EN)](https://blog.novelai.net/release-novelai-anime-diffusion-v4-curated-preview-en-ca4b0b11e671)
17
+ - [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
18
 
39
- ### Usage 🖥️
19
+ ### 📦 Usage
40
20
 
41
21
  ```shell
42
22
  pip -U install novelai-python
43
23
  ```
44
24
 
45
- More examples can be found in the [playground](https://github.com/LlmKira/novelai-python/tree/main/playground)
46
- directory, read code as documentation.
25
+ **More examples can be found in the [playground](https://github.com/LlmKira/novelai-python/tree/main/playground)
26
+ directory, read code as documentation.**
47
27
 
48
28
  ```python
49
29
  import asyncio
@@ -53,17 +33,42 @@ from dotenv import load_dotenv
53
33
  from pydantic import SecretStr
54
34
 
55
35
  from novelai_python import GenerateImageInfer, ImageGenerateResp, ApiCredential
36
+ from novelai_python.sdk.ai.generate_image import Model, Character, Sampler, UCPreset
37
+ from novelai_python.sdk.ai.generate_image.schema import PositionMap
56
38
 
57
39
  load_dotenv()
58
- enhance = "year 2023,dynamic angle, best quality, amazing quality, very aesthetic, absurdres"
59
40
  session = ApiCredential(api_token=SecretStr(os.getenv("NOVELAI_JWT"))) # pst-***
60
41
 
42
+ prompt = "1girl, year 2023,dynamic angle, best quality, amazing quality, very aesthetic, absurdres"
43
+
61
44
 
62
45
  async def main():
63
- gen = await GenerateImageInfer.build(prompt=f"1girl,{enhance}")
46
+ gen = GenerateImageInfer.build_generate(
47
+ prompt=prompt,
48
+ model=Model.NAI_DIFFUSION_4_CURATED_PREVIEW,
49
+ character_prompts=[
50
+ Character(
51
+ prompt="1girl",
52
+ uc="red hair",
53
+ center=PositionMap.AUTO
54
+ ),
55
+ Character(
56
+ prompt="1boy",
57
+ center=PositionMap.E5
58
+ )
59
+ ],
60
+ sampler=Sampler.K_EULER_ANCESTRAL,
61
+ ucPreset=UCPreset.TYPE0,
62
+ # Recommended, using preset negative_prompt depends on selected model
63
+ qualitySuffix=True,
64
+ qualityToggle=True,
65
+ decrisp_mode=False,
66
+ variety_boost=True,
67
+ # Checkbox in novelai.net
68
+ )
64
69
  cost = gen.calculate_cost(is_opus=True)
65
70
  print(f"charge: {cost} if you are vip3")
66
- resp = gen.request(session=session)
71
+ resp = await gen.request(session=session)
67
72
  resp: ImageGenerateResp
68
73
  print(resp.meta)
69
74
  file = resp.files[0]
@@ -76,7 +81,7 @@ loop.run_until_complete(main())
76
81
 
77
82
  ```
78
83
 
79
- #### LLM
84
+ #### 📦 LLM
80
85
 
81
86
  ```python
82
87
  import asyncio
@@ -127,7 +132,7 @@ loop = asyncio.get_event_loop()
127
132
  loop.run_until_complete(chat("Hello"))
128
133
  ```
129
134
 
130
- #### Random Prompt
135
+ #### 📦 Random Prompt
131
136
 
132
137
  ```python
133
138
  from novelai_python.tool.random_prompt import RandomPromptGenerator
@@ -136,14 +141,14 @@ prompt = RandomPromptGenerator(nsfw_enabled=False).random_prompt()
136
141
  print(prompt)
137
142
  ```
138
143
 
139
- #### Run A Server
144
+ #### 📦 Run A Server
140
145
 
141
146
  ```shell
142
147
  pip install novelai_python
143
148
  python3 -m novelai_python.server -h '127.0.0.1' -p 7888
144
149
  ```
145
150
 
146
- #### Tokenizer
151
+ #### 📦 Tokenizer
147
152
 
148
153
  ```python
149
154
  from novelai_python._enum import get_tokenizer_model, TextLLMModel
@@ -158,7 +163,32 @@ print(tokenizer_package.decode(tokenizer_package.encode(t_text)))
158
163
 
159
164
  ```
160
165
 
161
- ## About Nsfw 🚫
166
+ ### 🔨 Roadmap
167
+
168
+ - [x] tool.random_prompt
169
+ - [x] tool.paint_mask
170
+ - [x] tool.image_metadata
171
+ - [x] tokenizer
172
+ - [x] /ai/generate-image
173
+ - [x] /user/subscription
174
+ - [x] /user/login
175
+ - [x] /user/information
176
+ - [x] /ai/upscale
177
+ - [x] /ai/generate-image/suggest-tags
178
+ - [x] /ai/generate-voice
179
+ - [x] /ai/generate-stream
180
+ - [x] /ai/generate
181
+ - [x] /ai/augment-image
182
+ - [ ] /ai/annotate-image
183
+ - [ ] /ai/classify
184
+ - [ ] /ai/generate-prompt
185
+
186
+ > GenerateImageInfer.calculate_cost is correct in most cases, but please request account information to get accurate
187
+ > consumption information.
188
+
189
+ > This repo is maintained by me personally now. If you have any questions, please feel free to open an issue.
190
+
191
+ ## 🚫 About Nsfw
162
192
 
163
193
  You might need some solutions for identifying NSFW content and adding a mosaic to prevent operational mishaps.
164
194
 
@@ -166,7 +196,7 @@ https://dghs-imgutils.deepghs.org/main/api_doc/detect/nudenet.html
166
196
 
167
197
  https://dghs-imgutils.deepghs.org/main/api_doc/operate/censor.html
168
198
 
169
- ## Acknowledgements 🙏
199
+ ## 🙏 Acknowledgements
170
200
 
171
201
  [BackEnd](https://api.novelai.net/docs)
172
202
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "novelai-python"
3
- version = "0.5.3"
3
+ version = "0.6.1"
4
4
  description = "NovelAI Python Binding With Pydantic"
5
5
  authors = [
6
6
  { name = "sudoskys", email = "coldlando@hotmail.com" },
@@ -9,7 +9,7 @@ dependencies = [
9
9
  "elara>=0.5.5",
10
10
  "loguru>=0.7.2",
11
11
  "pydantic-settings>=2.1.0",
12
- "pydantic>=2.5.3",
12
+ "pydantic>=2.9.0",
13
13
  "httpx>=0.26.0",
14
14
  "shortuuid>=1.0.11",
15
15
  "Pillow>=10.2.0",
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/1/26 上午10:51
3
3
  # @Author : sudoskys
4
4
  # @File : __init__.py.py
5
- # @Software: PyCharm
5
+
6
6
  from .ai.generate_image import ImageGenerateResp
7
7
  from .user.information import InformationResp
8
8
  from .user.login import LoginResp
@@ -2,4 +2,4 @@
2
2
  # @Time : 2024/1/26 上午11:20
3
3
  # @Author : sudoskys
4
4
  # @File : __init__.py
5
- # @Software: PyCharm
5
+
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/1/26 上午11:16
3
3
  # @Author : sudoskys
4
4
  # @File : text2image.py
5
- # @Software: PyCharm
5
+
6
6
  from typing import Tuple, List
7
7
 
8
8
  from pydantic import BaseModel
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/2/13 上午11:29
3
3
  # @Author : sudoskys
4
4
  # @File : upscale.py
5
- # @Software: PyCharm
5
+
6
6
  from typing import Tuple
7
7
 
8
8
  from pydantic import BaseModel
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/2/13 上午11:30
3
3
  # @Author : sudoskys
4
4
  # @File : schema.py
5
- # @Software: PyCharm
5
+
6
6
 
7
7
  from pydantic import BaseModel
8
8
 
@@ -2,4 +2,4 @@
2
2
  # @Time : 2024/2/7 上午9:57
3
3
  # @Author : sudoskys
4
4
  # @File : __init__.py.py
5
- # @Software: PyCharm
5
+
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/2/8 下午3:10
3
3
  # @Author : sudoskys
4
4
  # @File : information.py
5
- # @Software: PyCharm
5
+
6
6
 
7
7
  from pydantic import Field
8
8
 
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/2/7 上午11:57
3
3
  # @Author : sudoskys
4
4
  # @File : login.py
5
- # @Software: PyCharm
5
+
6
6
 
7
7
  from ..schema import RespBase
8
8
 
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/2/7 上午9:57
3
3
  # @Author : sudoskys
4
4
  # @File : subscription.py
5
- # @Software: PyCharm
5
+
6
6
  from typing import Optional, Dict, Any, List
7
7
 
8
8
  from pydantic import BaseModel, Field
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/2/8 下午3:05
3
3
  # @Author : sudoskys
4
4
  # @File : ApiToken.py
5
- # @Software: PyCharm
5
+
6
6
 
7
7
  import arrow
8
8
  import shortuuid
@@ -18,7 +18,7 @@ class ApiCredential(CredentialBase):
18
18
  ApiCredential is the base class for all credential.
19
19
  """
20
20
  api_token: SecretStr = Field(None, description="api token")
21
- _x_correlation_id: str = shortuuid.uuid()[0:6]
21
+ x_correlation_id: str = shortuuid.uuid()[0:6]
22
22
 
23
23
  async def get_session(self, timeout: int = 180, update_headers: dict = None):
24
24
  headers = {
@@ -29,7 +29,7 @@ class ApiCredential(CredentialBase):
29
29
  "Content-Type": "application/json",
30
30
  "Origin": "https://novelai.net",
31
31
  "Referer": "https://novelai.net/",
32
- "x-correlation-id": self._x_correlation_id,
32
+ "x-correlation-id": self.x_correlation_id,
33
33
  "x-initiated-at": f"{arrow.utcnow().isoformat()}Z",
34
34
  }
35
35
 
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/1/26 上午11:04
3
3
  # @Author : sudoskys
4
4
  # @File : JwtToken.py
5
- # @Software: PyCharm
5
+
6
6
 
7
7
  import arrow
8
8
  import shortuuid
@@ -18,7 +18,7 @@ class JwtCredential(CredentialBase):
18
18
  JwtCredential is the base class for all credential.
19
19
  """
20
20
  jwt_token: SecretStr = Field(None, description="jwt token")
21
- _x_correlation_id: str = shortuuid.uuid()[0:6]
21
+ x_correlation_id: str = shortuuid.uuid()[0:6]
22
22
 
23
23
  async def get_session(self, timeout: int = 180, update_headers: dict = None):
24
24
  headers = {
@@ -29,7 +29,7 @@ class JwtCredential(CredentialBase):
29
29
  "Content-Type": "application/json",
30
30
  "Origin": "https://novelai.net",
31
31
  "Referer": "https://novelai.net/",
32
- "x-correlation-id": self._x_correlation_id,
32
+ "x-correlation-id": self.x_correlation_id,
33
33
  "x-initiated-at": f"{arrow.utcnow().isoformat()}Z",
34
34
  }
35
35
 
@@ -19,9 +19,9 @@ class LoginCredential(CredentialBase):
19
19
  """
20
20
  username: str = Field(None, description="username")
21
21
  password: SecretStr = Field(None, description="password")
22
- _session_headers: dict = {}
23
- _update_at: Optional[int] = None
24
- _x_correlation_id: str = shortuuid.uuid()[0:6]
22
+ session_headers: dict = Field(default_factory=dict)
23
+ update_at: Optional[int] = None
24
+ x_correlation_id: str = shortuuid.uuid()[0:6]
25
25
 
26
26
  async def get_session(self, timeout: int = 180, update_headers: dict = None):
27
27
  headers = {
@@ -32,19 +32,19 @@ class LoginCredential(CredentialBase):
32
32
  "Content-Type": "application/json",
33
33
  "Origin": "https://novelai.net",
34
34
  "Referer": "https://novelai.net/",
35
- "x-correlation-id": self._x_correlation_id,
35
+ "x-correlation-id": self.x_correlation_id,
36
36
  "x-initiated-at": f"{arrow.utcnow().isoformat()}Z",
37
37
  }
38
38
 
39
39
  # 30 天有效期
40
- if not self._session_headers or int(time.time()) - self._update_at > 29 * 24 * 60 * 60:
40
+ if not self.session_headers or int(time.time()) - self.update_at > 29 * 24 * 60 * 60:
41
41
  from ..sdk import Login
42
42
  resp = await Login.build(user_name=self.username, password=self.password.get_secret_value()).request()
43
43
  headers["Authorization"] = f"Bearer {resp.accessToken}"
44
- self._session_headers = headers
45
- self._update_at = int(time.time())
44
+ self.session_headers = headers
45
+ self.update_at = int(time.time())
46
46
  else:
47
- headers.update(self._session_headers)
47
+ headers.update(self.session_headers)
48
48
 
49
49
  if update_headers:
50
50
  headers.update(update_headers)
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/1/26 上午10:51
3
3
  # @Author : sudoskys
4
4
  # @File : __init__.py.py
5
- # @Software: PyCharm
5
+
6
6
  from pydantic import SecretStr
7
7
 
8
8
  from .ApiToken import ApiCredential
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/2/7 下午12:14
3
3
  # @Author : sudoskys
4
4
  # @File : _shema.py
5
- # @Software: PyCharm
5
+
6
6
  from curl_cffi.requests import AsyncSession
7
7
  from fake_useragent import UserAgent
8
8
  from pydantic import BaseModel
@@ -2,7 +2,7 @@
2
2
  # @Time : 2024/1/26 上午10:51
3
3
  # @Author : sudoskys
4
4
  # @File : __init__.py.py
5
- # @Software: PyCharm
5
+
6
6
 
7
7
  from .ai.augment_image import AugmentImageInfer # noqa 401
8
8
  from .ai.generate import LLM, LLMResp # noqa 401
@@ -2,4 +2,4 @@
2
2
  # @Time : 2024/1/26 上午11:20
3
3
  # @Author : sudoskys
4
4
  # @File : __init__.py.py
5
- # @Software: PyCharm
5
+
@@ -11,9 +11,9 @@ from novelai_python.sdk.ai._enum import Sampler, ModelGroups, get_model_group, M
11
11
  class Args(BaseModel):
12
12
  height: int
13
13
  width: int
14
- image: Optional[str]
14
+ image: bool
15
15
  n_samples: int
16
- strength: float
16
+ strength: Optional[float]
17
17
  steps: int
18
18
  sm: bool
19
19
  sm_dyn: bool
@@ -34,11 +34,10 @@ class CostCalculator:
34
34
  width: int,
35
35
  height: int,
36
36
  steps: int,
37
- image: str,
37
+ image: bool,
38
38
  n_samples: int,
39
39
  account_tier: int,
40
- strength: float,
41
-
40
+ strength: Optional[float],
42
41
  is_sm_enabled: bool,
43
42
  is_sm_dynamic: bool,
44
43
  is_account_active: bool,
@@ -138,14 +137,15 @@ class CostCalculator:
138
137
  dimension = 65536
139
138
 
140
139
  base_dimension = 1048576
141
- strength_multiplier = params.strength if params.image else 1
140
+ strength_multiplier = params.strength if (isinstance(params.strength, float) and params.image) else 1
142
141
  steps = params.steps
143
142
  samples = params.n_samples
144
143
 
145
144
  if steps <= 28 and dimension <= base_dimension and account_tier >= 3 and is_account_active and not is_tool_active:
146
145
  samples -= 1
147
146
 
148
- if model_group and model_group in [ModelGroups.STABLE_DIFFUSION_XL, ModelGroups.STABLE_DIFFUSION_XL_FURRY]:
147
+ if model_group and model_group in [ModelGroups.STABLE_DIFFUSION_XL, ModelGroups.STABLE_DIFFUSION_XL_FURRY,
148
+ ModelGroups.V4]:
149
149
  cost = calculate_dimension_cost(img_width, img_height, steps, params.sm, params.sm_dyn)
150
150
  elif dimension <= base_dimension and params.sampler in [
151
151
  Sampler.PLMS, Sampler.DDIM,