Skip to content

Commit f68526a

Browse files
authored
Merge pull request #122 from LlmKira/dev
fix: using Google Chrome
2 parents f57d334 + c33a684 commit f68526a

File tree

20 files changed

+83
-264
lines changed

20 files changed

+83
-264
lines changed

pdm.lock

Lines changed: 10 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playground/generate_image.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# @File : __init__.py.py
55

66
import asyncio
7+
import base64
78
import os
89
import pathlib
910
import random
@@ -55,7 +56,7 @@ async def generate(
5556
scene = prompt_generator.generate_scene_composition()
5657
if prompt is None:
5758
prompt = scene.pop(0) + ','.join([
58-
'muelsyse (arknights) '
59+
'muelsyse (arknights)'
5960
])
6061
character = [
6162
Character(
@@ -74,11 +75,11 @@ async def generate(
7475
# Generate
7576
try:
7677
agent = GenerateImageInfer.build_generate(
77-
prompt=prompt,
78-
width=832,
79-
height=1216,
78+
prompt=os.getenv("TEST_TAG", prompt),
79+
width=1024,
80+
height=1024,
8081
model=model,
81-
character_prompts=character,
82+
character_prompts=None if os.getenv("TEST_TAG") else character,
8283
sampler=Sampler.K_EULER_ANCESTRAL,
8384
ucPreset=UCPreset.TYPE0,
8485
# Recommended, using preset negative_prompt depends on selected model
@@ -110,7 +111,7 @@ async def direct_use():
110111
:return:
111112
"""
112113
credential = ApiCredential(api_token=SecretStr("pst-5555"))
113-
result = await GenerateImageInfer(
114+
result: ImageGenerateResp = await GenerateImageInfer(
114115
input="1girl",
115116
model=Model.NAI_DIFFUSION_4_5_FULL,
116117
parameters=Params(
@@ -127,6 +128,9 @@ async def direct_use():
127128
)
128129
).request(session=credential)
129130
print(f"Meta: {result.meta}")
131+
file = result.files[0]
132+
with open(f"{pathlib.Path(__file__).stem}.png", "wb") as f:
133+
f.write(file[1])
130134

131135

132136
load_dotenv()

playground/generate_image_img2img.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from novelai_python import APIError, LoginCredential
1616
from novelai_python import GenerateImageInfer, ImageGenerateResp, ApiCredential
17+
from novelai_python.sdk.ai._enum import Model
1718
from novelai_python.sdk.ai.generate_image import Action, Sampler
1819
from novelai_python.utils.useful import enum_to_list
1920

@@ -42,11 +43,10 @@ async def generate(
4243
image = base64.b64encode(f.read()).decode()
4344
# image = f.read() # Or you can use the raw bytes
4445
agent = GenerateImageInfer.build_img2img(
46+
model=Model.NAI_DIFFUSION_4_5_FULL,
4547
prompt=prompt,
4648
sampler=Sampler.K_DPMPP_SDE,
4749
image=image,
48-
seed=123456789,
49-
extra_noise_seed=123123123,
5050
)
5151
print(f"charge: {agent.calculate_cost(is_opus=True)} if you are vip3")
5252
print(f"charge: {agent.calculate_cost(is_opus=False)} if you are not vip3")

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "novelai-python"
3-
version = "0.7.10"
3+
version = "0.7.11"
44
description = "NovelAI Python Binding With Pydantic"
55
authors = [
66
{ name = "sudoskys", email = "coldlando@hotmail.com" },
@@ -13,7 +13,7 @@ dependencies = [
1313
"httpx>=0.26.0",
1414
"shortuuid>=1.0.11",
1515
"Pillow>=10.2.0",
16-
"curl-cffi>=0.9.0",
16+
"curl-cffi>=0.11.3",
1717
"fastapi>=0.109.0",
1818
"uvicorn[standard]>=0.27.0.post1",
1919
"numpy>=1.24.4",

src/novelai_python/credential/ApiToken.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from loguru import logger
1111
from pydantic import SecretStr, Field, field_validator
1212

13-
from ._base import CredentialBase, FAKE_UA
13+
from ._base import CredentialBase
1414

1515

1616
class ApiCredential(CredentialBase):
@@ -22,13 +22,8 @@ class ApiCredential(CredentialBase):
2222

2323
async def get_session(self, timeout: int = 180, update_headers: dict = None):
2424
headers = {
25-
"Accept": "*/*",
26-
"Accept-Encoding": "gzip, deflate, br",
27-
"User-Agent": FAKE_UA.edge,
2825
"Authorization": f"Bearer {self.api_token.get_secret_value()}",
2926
"Content-Type": "application/json",
30-
"Origin": "https://novelai.net",
31-
"Referer": "https://novelai.net/",
3227
"x-correlation-id": self.x_correlation_id,
3328
"x-initiated-at": f"{arrow.utcnow().isoformat()}Z",
3429
}
@@ -37,10 +32,10 @@ async def get_session(self, timeout: int = 180, update_headers: dict = None):
3732
assert isinstance(update_headers, dict), "update_headers must be a dict"
3833
headers.update(update_headers)
3934

40-
return AsyncSession(timeout=timeout, headers=headers, impersonate="edge101")
35+
return AsyncSession(timeout=timeout, headers=headers, impersonate="chrome136")
4136

4237
@field_validator('api_token')
4338
def check_api_token(cls, v: SecretStr):
4439
if not v.get_secret_value().startswith("pst"):
4540
logger.warning("api token should start with `pst-`")
46-
return v
41+
return v

src/novelai_python/credential/JwtToken.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from loguru import logger
1111
from pydantic import SecretStr, Field, field_validator
1212

13-
from ._base import CredentialBase, FAKE_UA
13+
from ._base import CredentialBase
1414

1515

1616
class JwtCredential(CredentialBase):
@@ -22,13 +22,8 @@ class JwtCredential(CredentialBase):
2222

2323
async def get_session(self, timeout: int = 180, update_headers: dict = None):
2424
headers = {
25-
"Accept": "*/*",
26-
"User-Agent": FAKE_UA.edge,
27-
"Accept-Encoding": "gzip, deflate, br",
2825
"Authorization": f"Bearer {self.jwt_token.get_secret_value()}",
2926
"Content-Type": "application/json",
30-
"Origin": "https://novelai.net",
31-
"Referer": "https://novelai.net/",
3227
"x-correlation-id": self.x_correlation_id,
3328
"x-initiated-at": f"{arrow.utcnow().isoformat()}Z",
3429
}
@@ -37,10 +32,10 @@ async def get_session(self, timeout: int = 180, update_headers: dict = None):
3732
assert isinstance(update_headers, dict), "update_headers must be a dict"
3833
headers.update(update_headers)
3934

40-
return AsyncSession(timeout=timeout, headers=headers, impersonate="edge101")
35+
return AsyncSession(timeout=timeout, headers=headers, impersonate="chrome136")
4136

4237
@field_validator('jwt_token')
4338
def check_jwt_token(cls, v: SecretStr):
4439
if not v.get_secret_value().startswith("ey"):
4540
logger.warning("jwt_token should start with ey")
46-
return v
41+
return v

src/novelai_python/credential/UserAuth.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from curl_cffi.requests import AsyncSession
1111
from pydantic import SecretStr, Field
1212

13-
from ._base import CredentialBase, FAKE_UA
13+
from ._base import CredentialBase
1414

1515

1616
class LoginCredential(CredentialBase):
@@ -25,13 +25,8 @@ class LoginCredential(CredentialBase):
2525

2626
async def get_session(self, timeout: int = 180, update_headers: dict = None):
2727
headers = {
28-
"Accept": "*/*",
29-
"User-Agent": FAKE_UA.edge,
30-
"Accept-Encoding": "gzip, deflate, br",
3128
"Authorization": "Bearer ",
3229
"Content-Type": "application/json",
33-
"Origin": "https://novelai.net",
34-
"Referer": "https://novelai.net/",
3530
"x-correlation-id": self.x_correlation_id,
3631
"x-initiated-at": f"{arrow.utcnow().isoformat()}Z",
3732
}
@@ -49,4 +44,4 @@ async def get_session(self, timeout: int = 180, update_headers: dict = None):
4944
if update_headers:
5045
headers.update(update_headers)
5146

52-
return AsyncSession(timeout=timeout, headers=headers, impersonate="edge101")
47+
return AsyncSession(timeout=timeout, headers=headers, impersonate="chrome136")

src/novelai_python/sdk/ai/_enum.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,17 @@ class SupportCondition:
217217
img2imgInpainting: bool
218218

219219

220-
def get_supported_params(model: Model):
220+
def get_supported_params(model: ModelTypeAlias):
221221
"""
222222
Get supported parameters for a given model
223223
:param model: Model
224224
:return: SupportCondition
225225
"""
226+
if isinstance(model, str):
227+
try:
228+
model = Model(model)
229+
except ValueError:
230+
pass
226231
if model in [
227232
Model.STABLE_DIFFUSION,
228233
Model.NAI_DIFFUSION,

src/novelai_python/sdk/ai/augment_image/__init__.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -174,28 +174,6 @@ def build(cls,
174174
prompt=prompt,
175175
)
176176

177-
async def necessary_headers(self, request_data) -> dict:
178-
"""
179-
:param request_data:
180-
:return:
181-
"""
182-
return {
183-
"Host": urlparse(self.endpoint).netloc,
184-
"Accept": "*/*",
185-
"Accept-Encoding": "gzip, deflate, br",
186-
"Referer": "https://novelai.net/",
187-
"Content-Type": "application/json",
188-
"Origin": "https://novelai.net",
189-
"Content-Length": str(len(json.dumps(request_data).encode("utf-8"))),
190-
"Connection": "keep-alive",
191-
"Sec-Fetch-Dest": "empty",
192-
"Sec-Fetch-Mode": "cors",
193-
"Sec-Fetch-Site": "same-site",
194-
"Pragma": "no-cache",
195-
"Cache-Control": "no-cache",
196-
'priority': "u=1, i"
197-
}
198-
199177
@retry(
200178
wait=wait_random(min=1, max=3),
201179
stop=stop_after_attempt(3),
@@ -216,7 +194,6 @@ async def request(self,
216194
# Prepare request data
217195
request_data = self.model_dump(mode="json", exclude_none=True)
218196
async with session if isinstance(session, AsyncSession) else await session.get_session() as sess:
219-
sess.headers.update(await self.necessary_headers(request_data))
220197
if override_headers:
221198
sess.headers.clear()
222199
sess.headers.update(override_headers)

src/novelai_python/sdk/ai/generate/__init__.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,6 @@ def endpoint(self, value):
6565
def base_url(self):
6666
return f"{self.endpoint.strip('/')}/ai/generate"
6767

68-
async def necessary_headers(self, request_data) -> dict:
69-
"""
70-
:param request_data: dict
71-
:return: dict
72-
"""
73-
return {
74-
"Host": urlparse(self.endpoint).netloc,
75-
"accept": "*/*",
76-
"accept-language": "zh-CN,zh;q=0.9",
77-
"cache-control": "no-cache",
78-
"content-type": "application/json",
79-
"pragma": "no-cache",
80-
"Referer": "https://novelai.net/",
81-
"Referrer-Policy": "strict-origin-when-cross-origin"
82-
}
83-
8468
@model_validator(mode="after")
8569
def normalize_model(self):
8670
if self.model in [
@@ -361,7 +345,6 @@ async def request(self,
361345
}
362346
async with session if isinstance(session, AsyncSession) else await session.get_session() as sess:
363347
# Header
364-
sess.headers.update(await self.necessary_headers(request_data))
365348
if override_headers:
366349
sess.headers.clear()
367350
sess.headers.update(override_headers)

0 commit comments

Comments
 (0)