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.
- {novelai_python-0.5.3 → novelai_python-0.6.1}/PKG-INFO +67 -37
- {novelai_python-0.5.3 → novelai_python-0.6.1}/README.md +65 -35
- {novelai_python-0.5.3 → novelai_python-0.6.1}/pyproject.toml +2 -2
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/__init__.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/__init__.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/generate_image.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/upscale.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/schema.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/user/__init__.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/user/information.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/user/login.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/user/subscription.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/credential/ApiToken.py +3 -3
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/credential/JwtToken.py +3 -3
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/credential/UserAuth.py +8 -8
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/credential/__init__.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/credential/_base.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/__init__.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/__init__.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/_cost.py +7 -7
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/_enum.py +158 -2
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/augment_image/__init__.py +3 -3
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate/__init__.py +1 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate/_schema.py +17 -15
- novelai_python-0.6.1/src/novelai_python/sdk/ai/generate_image/__init__.py +994 -0
- novelai_python-0.6.1/src/novelai_python/sdk/ai/generate_image/schema.py +129 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate_image/suggest_tags.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/upscale.py +0 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/schema.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/user/__init__.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/user/information.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/user/login.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/user/subscription.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/clip_simple_tokenizer.py +3 -2
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/random_prompt/tag.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/random_prompt/tag_character.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/random_prompt/tag_nsfw.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/utils/__init__.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/utils/useful.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_random_prompt.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_server.py +7 -2
- {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_server_run.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_upscale.py +2 -2
- {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_user_information.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_user_login.py +1 -1
- {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/test_user_subscription.py +1 -1
- novelai_python-0.5.3/src/novelai_python/sdk/ai/generate_image/__init__.py +0 -741
- {novelai_python-0.5.3 → novelai_python-0.6.1}/LICENSE +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/NOTICE.MD +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/__init__.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_enum.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_exceptions.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/generate.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/generate_stream.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/_response/ai/generate_voice.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/LICENSE +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/_const.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/augment_image/_enum.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate/_const.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate/_enum.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate/themes.json +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate_stream.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate_voice/__init__.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/sdk/ai/generate_voice/_enum.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/server.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/__init__.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/nerdstash_v1.model +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/nerdstash_v2.model +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/novelai.model +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tokenizer/novelai_v2.model +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/__init__.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/image_metadata/__init__.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/image_metadata/_type.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/image_metadata/bch_utils.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/image_metadata/lsb_extractor.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/image_metadata/lsb_injector.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/paint_mask/__init__.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/tool/random_prompt/__init__.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/src/novelai_python/utils/encode.py +0 -0
- {novelai_python-0.5.3 → novelai_python-0.6.1}/tests/__init__.py +0 -0
- {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.
|
|
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.
|
|
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
|
-
###
|
|
52
|
+
### 📰 News
|
|
53
53
|
|
|
54
|
-
- [
|
|
55
|
-
- [
|
|
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 =
|
|
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
|
-
|
|
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
|
-
###
|
|
14
|
+
### 📰 News
|
|
15
15
|
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
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 =
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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/2/8 下午3:05
|
|
3
3
|
# @Author : sudoskys
|
|
4
4
|
# @File : ApiToken.py
|
|
5
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
45
|
-
self.
|
|
44
|
+
self.session_headers = headers
|
|
45
|
+
self.update_at = int(time.time())
|
|
46
46
|
else:
|
|
47
|
-
headers.update(self.
|
|
47
|
+
headers.update(self.session_headers)
|
|
48
48
|
|
|
49
49
|
if update_headers:
|
|
50
50
|
headers.update(update_headers)
|
|
@@ -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:
|
|
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:
|
|
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,
|