novelai-python 0.2.9__tar.gz → 0.3.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 (50) hide show
  1. {novelai_python-0.2.9 → novelai_python-0.3.0}/PKG-INFO +2 -1
  2. {novelai_python-0.2.9 → novelai_python-0.3.0}/pyproject.toml +2 -1
  3. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/sdk/ai/generate_image.py +10 -8
  4. novelai_python-0.3.0/src/novelai_python/utils/useful.py +104 -0
  5. novelai_python-0.2.9/src/novelai_python/utils/useful.py +0 -44
  6. {novelai_python-0.2.9 → novelai_python-0.3.0}/LICENSE +0 -0
  7. {novelai_python-0.2.9 → novelai_python-0.3.0}/NOTICE.MD +0 -0
  8. {novelai_python-0.2.9 → novelai_python-0.3.0}/README.md +0 -0
  9. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/__init__.py +0 -0
  10. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/_exceptions.py +0 -0
  11. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/_response/__init__.py +0 -0
  12. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/_response/ai/__init__.py +0 -0
  13. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/_response/ai/generate_image.py +0 -0
  14. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/_response/ai/upscale.py +0 -0
  15. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/_response/schema.py +0 -0
  16. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/_response/user/__init__.py +0 -0
  17. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/_response/user/information.py +0 -0
  18. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/_response/user/login.py +0 -0
  19. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/_response/user/subscription.py +0 -0
  20. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/credential/ApiToken.py +0 -0
  21. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/credential/JwtToken.py +0 -0
  22. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/credential/UserAuth.py +0 -0
  23. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/credential/__init__.py +0 -0
  24. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/credential/_base.py +0 -0
  25. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/sdk/__init__.py +0 -0
  26. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/sdk/ai/LICENSE +0 -0
  27. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/sdk/ai/__init__.py +0 -0
  28. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/sdk/ai/upscale.py +0 -0
  29. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/sdk/schema.py +0 -0
  30. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/sdk/user/__init__.py +0 -0
  31. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/sdk/user/information.py +0 -0
  32. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/sdk/user/login.py +0 -0
  33. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/sdk/user/subscription.py +0 -0
  34. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/server.py +0 -0
  35. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/utils/__init__.py +0 -0
  36. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/utils/encode.py +0 -0
  37. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/utils/hash.py +0 -0
  38. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/utils/random_prompt/__init__.py +0 -0
  39. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/utils/random_prompt/tag.py +0 -0
  40. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/utils/random_prompt/tag_artist.py +0 -0
  41. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/utils/random_prompt/tag_character.py +0 -0
  42. {novelai_python-0.2.9 → novelai_python-0.3.0}/src/novelai_python/utils/random_prompt/tag_nsfw.py +0 -0
  43. {novelai_python-0.2.9 → novelai_python-0.3.0}/tests/__init__.py +0 -0
  44. {novelai_python-0.2.9 → novelai_python-0.3.0}/tests/test_random_prompt.py +0 -0
  45. {novelai_python-0.2.9 → novelai_python-0.3.0}/tests/test_server.py +0 -0
  46. {novelai_python-0.2.9 → novelai_python-0.3.0}/tests/test_server_run.py +0 -0
  47. {novelai_python-0.2.9 → novelai_python-0.3.0}/tests/test_upscale.py +0 -0
  48. {novelai_python-0.2.9 → novelai_python-0.3.0}/tests/test_user_information.py +0 -0
  49. {novelai_python-0.2.9 → novelai_python-0.3.0}/tests/test_user_login.py +0 -0
  50. {novelai_python-0.2.9 → novelai_python-0.3.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.2.9
3
+ Version: 0.3.0
4
4
  Summary: Novelai Python Binding With Pydantic
5
5
  Author-Email: sudoskys <coldlando@hotmail.com>
6
6
  License: Apache License 2.0
@@ -19,6 +19,7 @@ Requires-Dist: fastapi>=0.109.0
19
19
  Requires-Dist: uvicorn[standard]>=0.27.0.post1
20
20
  Requires-Dist: numpy>=1.24.4
21
21
  Requires-Dist: argon2-cffi>=23.1.0
22
+ Requires-Dist: opencv-python>=4.8.1.78
22
23
  Requires-Dist: pytest>=7.4.4; extra == "testing"
23
24
  Requires-Dist: pytest-asyncio>=0.23.4; extra == "testing"
24
25
  Provides-Extra: testing
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "novelai-python"
3
- version = "0.2.9"
3
+ version = "0.3.0"
4
4
  description = "Novelai Python Binding With Pydantic"
5
5
  authors = [
6
6
  { name = "sudoskys", email = "coldlando@hotmail.com" },
@@ -18,6 +18,7 @@ dependencies = [
18
18
  "uvicorn[standard]>=0.27.0.post1",
19
19
  "numpy>=1.24.4",
20
20
  "argon2-cffi>=23.1.0",
21
+ "opencv-python>=4.8.1.78",
21
22
  ]
22
23
  requires-python = ">=3.8"
23
24
  readme = "README.md"
@@ -207,6 +207,14 @@ class GenerateImageInfer(ApiBaseModel):
207
207
  parameters: Params = Params()
208
208
  model_config = ConfigDict(extra="ignore")
209
209
 
210
+ @property
211
+ def endpoint(self):
212
+ return self._endpoint
213
+
214
+ @endpoint.setter
215
+ def endpoint(self, value):
216
+ self._endpoint = value
217
+
210
218
  @override
211
219
  def model_post_init(self, *args) -> None:
212
220
  """
@@ -241,20 +249,14 @@ class GenerateImageInfer(ApiBaseModel):
241
249
  def validate_model(self):
242
250
  if self.action == Action.INFILL and not self.parameters.mask:
243
251
  logger.warning("Mask maybe required for infill mode.")
252
+ if self.action == Action.INFILL:
253
+ self.parameters.extra_noise_seed = self.parameters.seed
244
254
  return self
245
255
 
246
256
  @property
247
257
  def base_url(self):
248
258
  return f"{self.endpoint.strip('/')}/ai/generate-image"
249
259
 
250
- @property
251
- def endpoint(self):
252
- return self._endpoint
253
-
254
- @endpoint.setter
255
- def endpoint(self, value):
256
- self._endpoint = value
257
-
258
260
  def calculate_cost(self, is_opus: bool = False):
259
261
  """
260
262
  Calculate the Anlas cost of current parameters.
@@ -0,0 +1,104 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Time : 2024/2/9 下午10:41
3
+ # @Author : sudoskys
4
+ # @File : useful.py
5
+ # @Software: PyCharm
6
+ import collections
7
+ import random
8
+ from typing import List, Union
9
+
10
+ import cv2 as cv
11
+ import numpy as np
12
+
13
+
14
+ def enum_to_list(enum_):
15
+ return list(map(lambda x: x.value, enum_._member_map_.values()))
16
+
17
+
18
+ class QueSelect(object):
19
+ def __init__(self, data: List[str]):
20
+ """
21
+ A queue selector
22
+ :param data:
23
+ """
24
+ self.data = collections.deque(data)
25
+ self.used = collections.deque()
26
+ self.users = {}
27
+
28
+ def get(self, user_id: Union[int, str]) -> str:
29
+ user_id = str(user_id)
30
+ if user_id not in self.users:
31
+ self.users[user_id] = {'data': self.data.copy(), 'used': collections.deque()}
32
+
33
+ user_data = self.users[user_id]['data']
34
+ user_used = self.users[user_id]['used']
35
+
36
+ if len(user_data) == 0:
37
+ user_data, user_used = user_used, user_data
38
+ # 随机掉 User data
39
+ if len(user_data) > 2:
40
+ random.shuffle(user_data)
41
+ self.users[user_id]['data'] = user_data
42
+ self.users[user_id]['used'] = user_used
43
+
44
+ selected = user_data.popleft()
45
+ user_used.append(selected)
46
+
47
+ return selected
48
+
49
+
50
+ def create_mask_from_sketch(original_img_bytes: bytes,
51
+ sketch_img_bytes: bytes,
52
+ output_format: str = '.png',
53
+ jagged_edges: bool = True
54
+ ) -> bytes:
55
+ """
56
+ Function to create a mask from original and sketch images input as bytes. Returns bytes.
57
+
58
+ :param jagged_edges: Whether to create jagged edges in the mask. Defaults to False.
59
+ :param original_img_bytes: Bytes corresponding to the original image.
60
+ :param sketch_img_bytes: Bytes corresponding to the sketch image.
61
+ :param output_format: Format of the output image. Defaults to '.png'. It could also be '.jpg'
62
+ :returns bytes: Bytes corresponding to the resultant mask
63
+ """
64
+ # Load images
65
+ ori_img = cv.imdecode(np.frombuffer(original_img_bytes, np.uint8), cv.IMREAD_COLOR)
66
+ sketch_img = cv.imdecode(np.frombuffer(sketch_img_bytes, np.uint8), cv.IMREAD_COLOR)
67
+
68
+ # Check if images have the same size
69
+ if ori_img.shape != sketch_img.shape:
70
+ raise ValueError("Images must have the same size.")
71
+
72
+ # Calculate difference between the original and sketch images
73
+ diff_img = cv.absdiff(ori_img, sketch_img)
74
+
75
+ # Convert the difference image to grayscale
76
+ diff_gray = cv.cvtColor(diff_img, cv.COLOR_BGR2GRAY)
77
+
78
+ # Threshold to create the mask
79
+ _, thresh = cv.threshold(diff_gray, 10, 255, cv.THRESH_BINARY)
80
+
81
+ if jagged_edges:
82
+ # Use a bigger kernel for dilation to create larger 'step' effect at the edges
83
+ kernel = np.ones((7, 7), np.uint8)
84
+ else:
85
+ kernel = np.ones((3, 3), np.uint8)
86
+
87
+ # Perform morphological opening to remove small noise
88
+ opening = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel, iterations=2)
89
+
90
+ # Further remove noise with a Gaussian filter
91
+ smooth = cv.GaussianBlur(opening, (5, 5), 0)
92
+
93
+ if jagged_edges:
94
+ # Apply additional thresholding to create sharper, jagged edges
95
+ _, smooth = cv.threshold(smooth, 128, 255, cv.THRESH_BINARY)
96
+
97
+ # Convert image to BytesIO object
98
+ is_success, buffer = cv.imencode(output_format, smooth)
99
+ if is_success:
100
+ output_io = buffer.tobytes()
101
+ else:
102
+ raise ValueError("Error during conversion of image to BytesIO object")
103
+
104
+ return output_io
@@ -1,44 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # @Time : 2024/2/9 下午10:41
3
- # @Author : sudoskys
4
- # @File : useful.py
5
- # @Software: PyCharm
6
- import collections
7
- import random
8
- from typing import List, Union
9
-
10
-
11
- def enum_to_list(enum_):
12
- return list(map(lambda x: x.value, enum_._member_map_.values()))
13
-
14
-
15
- class QueSelect(object):
16
- def __init__(self, data: List[str]):
17
- """
18
- A queue selector
19
- :param data:
20
- """
21
- self.data = collections.deque(data)
22
- self.used = collections.deque()
23
- self.users = {}
24
-
25
- def get(self, user_id: Union[int, str]) -> str:
26
- user_id = str(user_id)
27
- if user_id not in self.users:
28
- self.users[user_id] = {'data': self.data.copy(), 'used': collections.deque()}
29
-
30
- user_data = self.users[user_id]['data']
31
- user_used = self.users[user_id]['used']
32
-
33
- if len(user_data) == 0:
34
- user_data, user_used = user_used, user_data
35
- # 随机掉 User data
36
- if len(user_data) > 2:
37
- random.shuffle(user_data)
38
- self.users[user_id]['data'] = user_data
39
- self.users[user_id]['used'] = user_used
40
-
41
- selected = user_data.popleft()
42
- user_used.append(selected)
43
-
44
- return selected
File without changes
File without changes
File without changes