Spaces:
Running
Running
Merge branch 'feature/random-colors'
Browse files- TODO +6 -0
- myapp/__main__.py +4 -0
- myapp/app.py +39 -4
- myapp/cli.py +60 -0
- myapp/cli/main.py +42 -0
- myapp/colorutils.py +33 -0
- myapp/palette.py +41 -0
- myapp/palette_demo.py +30 -0
- myapp/params.py +19 -0
- myapp/static/example.webp +0 -0
- myapp/static/vulture.webp +0 -0
- pyproject.toml +4 -0
- requirements.txt +10 -0
- uv.lock +82 -0
TODO
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Todo:
|
2 |
+
Gradio:
|
3 |
+
☐ Upload button
|
4 |
+
☐ Color group
|
5 |
+
CLI:
|
6 |
+
☐ Buffer context
|
myapp/__main__.py
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from myapp.cli import cli
|
2 |
+
|
3 |
+
if __name__ == "__main__":
|
4 |
+
cli()
|
myapp/app.py
CHANGED
@@ -2,7 +2,7 @@ import re
|
|
2 |
from functools import partial
|
3 |
from io import BytesIO
|
4 |
from pathlib import Path
|
5 |
-
from typing import Any
|
6 |
|
7 |
import gradio as gr
|
8 |
import segno
|
@@ -10,6 +10,10 @@ from gradio.components import Component
|
|
10 |
from huggingface_hub import InferenceClient
|
11 |
from PIL import Image
|
12 |
from qrcode_artistic import write_artistic
|
|
|
|
|
|
|
|
|
13 |
|
14 |
try:
|
15 |
import dotenv
|
@@ -19,6 +23,7 @@ except ImportError:
|
|
19 |
pass
|
20 |
|
21 |
client = InferenceClient(model="black-forest-labs/FLUX.1-schnell")
|
|
|
22 |
|
23 |
MODELS = [
|
24 |
"stabilityai/stable-diffusion-3.5-large",
|
@@ -39,13 +44,20 @@ with gr.Blocks() as demo:
|
|
39 |
|
40 |
with gr.Column():
|
41 |
output = gr.Image()
|
42 |
-
background = gr.Image(
|
|
|
|
|
43 |
scale = gr.Slider(3, 15, 9, step=1, label="Scale")
|
|
|
44 |
|
45 |
with gr.Row():
|
46 |
color_dark = gr.ColorPicker("#000000", label="Dark")
|
47 |
color_light = gr.ColorPicker("#FFFFFF", label="Light")
|
48 |
|
|
|
|
|
|
|
|
|
49 |
def generate_background(data: dict[Component, Any]):
|
50 |
if not data.get(prompt):
|
51 |
return gr.skip(), gr.skip()
|
@@ -57,6 +69,9 @@ with gr.Blocks() as demo:
|
|
57 |
return None
|
58 |
|
59 |
def to_hex_format(value: str):
|
|
|
|
|
|
|
60 |
if value.startswith("#"):
|
61 |
return value
|
62 |
|
@@ -66,7 +81,7 @@ with gr.Blocks() as demo:
|
|
66 |
return f"#{r:02X}{g:02X}{b:02X}"
|
67 |
|
68 |
image = Image.open(data[background])
|
69 |
-
qr_code = segno.make(data[text], error=
|
70 |
|
71 |
with BytesIO() as buffer:
|
72 |
write_artistic(
|
@@ -77,12 +92,23 @@ with gr.Blocks() as demo:
|
|
77 |
scale=data[scale],
|
78 |
light=to_hex_format(data[color_light]),
|
79 |
dark=to_hex_format(data[color_dark]),
|
|
|
80 |
)
|
81 |
|
82 |
return Image.open(buffer)
|
83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
gr.on(
|
85 |
-
[button.click, prompt.submit],
|
86 |
partial(gr.update, interactive=False),
|
87 |
outputs=button,
|
88 |
).then(
|
@@ -100,6 +126,7 @@ with gr.Blocks() as demo:
|
|
100 |
text.submit,
|
101 |
background.change,
|
102 |
scale.change,
|
|
|
103 |
color_light.change,
|
104 |
color_dark.change,
|
105 |
],
|
@@ -108,12 +135,20 @@ with gr.Blocks() as demo:
|
|
108 |
text,
|
109 |
background,
|
110 |
scale,
|
|
|
111 |
color_light,
|
112 |
color_dark,
|
113 |
},
|
114 |
outputs=output,
|
115 |
)
|
116 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
|
118 |
if __name__ == "__main__":
|
119 |
demo.launch()
|
|
|
2 |
from functools import partial
|
3 |
from io import BytesIO
|
4 |
from pathlib import Path
|
5 |
+
from typing import Any, cast
|
6 |
|
7 |
import gradio as gr
|
8 |
import segno
|
|
|
10 |
from huggingface_hub import InferenceClient
|
11 |
from PIL import Image
|
12 |
from qrcode_artistic import write_artistic
|
13 |
+
from segno.consts import ERROR_MAPPING
|
14 |
+
|
15 |
+
from myapp.colorutils import array_to_hex
|
16 |
+
from myapp.palette import extract_color_clusters, sort_color_clusters
|
17 |
|
18 |
try:
|
19 |
import dotenv
|
|
|
23 |
pass
|
24 |
|
25 |
client = InferenceClient(model="black-forest-labs/FLUX.1-schnell")
|
26 |
+
static_path = Path(__file__).parent.relative_to(Path.cwd()) / "static"
|
27 |
|
28 |
MODELS = [
|
29 |
"stabilityai/stable-diffusion-3.5-large",
|
|
|
44 |
|
45 |
with gr.Column():
|
46 |
output = gr.Image()
|
47 |
+
background = gr.Image(
|
48 |
+
str(static_path / "example.webp"), visible=False, type="filepath"
|
49 |
+
)
|
50 |
scale = gr.Slider(3, 15, 9, step=1, label="Scale")
|
51 |
+
error = gr.Radio(list(ERROR_MAPPING), value="H", label="Error")
|
52 |
|
53 |
with gr.Row():
|
54 |
color_dark = gr.ColorPicker("#000000", label="Dark")
|
55 |
color_light = gr.ColorPicker("#FFFFFF", label="Light")
|
56 |
|
57 |
+
with gr.Row():
|
58 |
+
extract_colors = gr.Button("Extract")
|
59 |
+
gr.ClearButton([color_dark, color_light], value="Reset")
|
60 |
+
|
61 |
def generate_background(data: dict[Component, Any]):
|
62 |
if not data.get(prompt):
|
63 |
return gr.skip(), gr.skip()
|
|
|
69 |
return None
|
70 |
|
71 |
def to_hex_format(value: str):
|
72 |
+
if value is None:
|
73 |
+
return None
|
74 |
+
|
75 |
if value.startswith("#"):
|
76 |
return value
|
77 |
|
|
|
81 |
return f"#{r:02X}{g:02X}{b:02X}"
|
82 |
|
83 |
image = Image.open(data[background])
|
84 |
+
qr_code = segno.make(data[text], error=data[error])
|
85 |
|
86 |
with BytesIO() as buffer:
|
87 |
write_artistic(
|
|
|
92 |
scale=data[scale],
|
93 |
light=to_hex_format(data[color_light]),
|
94 |
dark=to_hex_format(data[color_dark]),
|
95 |
+
quiet_zone=cast(Any, "#FFFFFF"),
|
96 |
)
|
97 |
|
98 |
return Image.open(buffer)
|
99 |
|
100 |
+
def generate_palette(data: dict[Component, Any]):
|
101 |
+
if data[background] is None:
|
102 |
+
return None, None
|
103 |
+
|
104 |
+
image = Image.open(data[background])
|
105 |
+
k_means = extract_color_clusters(image, n_clusters=2)
|
106 |
+
primary, secondary = map(array_to_hex, sort_color_clusters(k_means))
|
107 |
+
|
108 |
+
return primary, secondary
|
109 |
+
|
110 |
gr.on(
|
111 |
+
[button.click, prompt.submit, demo.load],
|
112 |
partial(gr.update, interactive=False),
|
113 |
outputs=button,
|
114 |
).then(
|
|
|
126 |
text.submit,
|
127 |
background.change,
|
128 |
scale.change,
|
129 |
+
error.change,
|
130 |
color_light.change,
|
131 |
color_dark.change,
|
132 |
],
|
|
|
135 |
text,
|
136 |
background,
|
137 |
scale,
|
138 |
+
error,
|
139 |
color_light,
|
140 |
color_dark,
|
141 |
},
|
142 |
outputs=output,
|
143 |
)
|
144 |
|
145 |
+
gr.on(
|
146 |
+
[extract_colors.click],
|
147 |
+
generate_palette,
|
148 |
+
inputs={background},
|
149 |
+
outputs=[color_dark, color_light],
|
150 |
+
)
|
151 |
+
|
152 |
|
153 |
if __name__ == "__main__":
|
154 |
demo.launch()
|
myapp/cli.py
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import click
|
2 |
+
import dotenv
|
3 |
+
import segno
|
4 |
+
from huggingface_hub import InferenceClient
|
5 |
+
from qrcode_artistic import write_artistic
|
6 |
+
from segno.consts import ERROR_MAPPING
|
7 |
+
|
8 |
+
from myapp.palette import extract_color_clusters, generate_palette_image
|
9 |
+
from myapp.params import ImageParamType
|
10 |
+
|
11 |
+
dotenv.load_dotenv()
|
12 |
+
client = InferenceClient()
|
13 |
+
|
14 |
+
|
15 |
+
@click.group()
|
16 |
+
def cli():
|
17 |
+
pass
|
18 |
+
|
19 |
+
|
20 |
+
@cli.command()
|
21 |
+
@click.option("--prompt", required=True)
|
22 |
+
@click.option("--target", type=click.Path(dir_okay=False), required=True)
|
23 |
+
@click.option("--model", default="black-forest-labs/FLUX.1-schnell")
|
24 |
+
@click.option("--width", default=400)
|
25 |
+
@click.option("--height", default=400)
|
26 |
+
def generate_image(prompt, target, model, width, height):
|
27 |
+
image = client.text_to_image(
|
28 |
+
prompt=prompt,
|
29 |
+
model=model,
|
30 |
+
width=width,
|
31 |
+
height=height,
|
32 |
+
)
|
33 |
+
|
34 |
+
image.save(target)
|
35 |
+
|
36 |
+
|
37 |
+
@cli.command()
|
38 |
+
@click.option("--image", type=ImageParamType(), required=True)
|
39 |
+
@click.option("--target", type=click.Path(dir_okay=False), required=True)
|
40 |
+
@click.option("--n-colors", default=4)
|
41 |
+
@click.option("--shade", "shades", default=(0.0,), multiple=True)
|
42 |
+
def generate_palette(image, target, n_colors, shades):
|
43 |
+
k_means = extract_color_clusters(image, n_colors)
|
44 |
+
palette = generate_palette_image(k_means, shades=shades)
|
45 |
+
palette.save(target)
|
46 |
+
|
47 |
+
|
48 |
+
@cli.command()
|
49 |
+
@click.option("--text", required=True)
|
50 |
+
@click.option("--background", type=ImageParamType(), required=True)
|
51 |
+
@click.option("--target", type=click.Path(dir_okay=False), required=True)
|
52 |
+
@click.option("--scale", type=click.IntRange(min=3, max=15), default=9)
|
53 |
+
@click.option("--error", type=click.Choice(list(ERROR_MAPPING)))
|
54 |
+
def generate_qr_code(text, background, target, scale, error):
|
55 |
+
write_artistic(
|
56 |
+
segno.make(text, error=error),
|
57 |
+
background.filename,
|
58 |
+
target,
|
59 |
+
scale=scale,
|
60 |
+
)
|
myapp/cli/main.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import click
|
2 |
+
import dotenv
|
3 |
+
from huggingface_hub import InferenceClient
|
4 |
+
|
5 |
+
from myapp.palette import extract_color_clusters, generate_palette_image
|
6 |
+
from myapp.params import ImageParamType
|
7 |
+
|
8 |
+
dotenv.load_dotenv()
|
9 |
+
client = InferenceClient()
|
10 |
+
|
11 |
+
|
12 |
+
@click.group()
|
13 |
+
def cli():
|
14 |
+
pass
|
15 |
+
|
16 |
+
|
17 |
+
@cli.command()
|
18 |
+
@click.option("--prompt", required=True)
|
19 |
+
@click.option("--target", type=click.Path(dir_okay=False), required=True)
|
20 |
+
@click.option("--model", default="black-forest-labs/FLUX.1-schnell")
|
21 |
+
@click.option("--width", default=400)
|
22 |
+
@click.option("--height", default=400)
|
23 |
+
def generate_image(prompt, target, model, width, height):
|
24 |
+
image = client.text_to_image(
|
25 |
+
prompt=prompt,
|
26 |
+
model=model,
|
27 |
+
width=width,
|
28 |
+
height=height,
|
29 |
+
)
|
30 |
+
|
31 |
+
image.save(target)
|
32 |
+
|
33 |
+
|
34 |
+
@cli.command()
|
35 |
+
@click.option("--image", type=ImageParamType(), required=True)
|
36 |
+
@click.option("--target", type=click.Path(dir_okay=False), required=True)
|
37 |
+
@click.option("--n-colors", default=4)
|
38 |
+
@click.option("--shade", "shades", default=(0.0,), multiple=True)
|
39 |
+
def generate_palette(image, target, n_colors, shades):
|
40 |
+
k_means = extract_color_clusters(image, n_colors)
|
41 |
+
palette = generate_palette_image(k_means, shades=shades)
|
42 |
+
palette.save(target)
|
myapp/colorutils.py
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import colorsys
|
2 |
+
from typing import NamedTuple
|
3 |
+
|
4 |
+
import numpy as np
|
5 |
+
|
6 |
+
|
7 |
+
class HSVUpdate(NamedTuple):
|
8 |
+
h: int = 0
|
9 |
+
s: int = 0
|
10 |
+
v: int = 0
|
11 |
+
|
12 |
+
def apply(self, color: np.ndarray):
|
13 |
+
hsv = colorsys.rgb_to_hsv(*color / 255)
|
14 |
+
tmp = np.add(hsv, self).clip(0, 1)
|
15 |
+
rgb = colorsys.hsv_to_rgb(*tmp)
|
16 |
+
|
17 |
+
return np.array(rgb) * 255
|
18 |
+
|
19 |
+
|
20 |
+
def get_hsv_value(cluster: np.ndarray):
|
21 |
+
return colorsys.rgb_to_hsv(*cluster / 255)[2]
|
22 |
+
|
23 |
+
|
24 |
+
def add_hsv_saturation(cluster: np.ndarray, delta: float):
|
25 |
+
h, s, v = colorsys.rgb_to_hsv(*cluster / 255)
|
26 |
+
s = max(0, min(1, s + delta))
|
27 |
+
|
28 |
+
return np.array(colorsys.hsv_to_rgb(h, s, v)) * 255
|
29 |
+
|
30 |
+
|
31 |
+
def array_to_hex(values: np.ndarray):
|
32 |
+
values = np.round(values).astype(int)
|
33 |
+
return "#" + ("{:02X}" * len(values)).format(*values)
|
myapp/palette.py
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import itertools
|
2 |
+
|
3 |
+
import numpy as np
|
4 |
+
from PIL import Image
|
5 |
+
from sklearn.cluster import KMeans
|
6 |
+
|
7 |
+
from myapp.colorutils import add_hsv_saturation, get_hsv_value
|
8 |
+
|
9 |
+
|
10 |
+
def extract_color_clusters(image_array: np.ndarray | Image.Image, n_clusters=2):
|
11 |
+
if not isinstance(image_array, np.ndarray):
|
12 |
+
image_array = np.array(image_array)
|
13 |
+
|
14 |
+
w, h, d = image_array.shape
|
15 |
+
pixels = image_array.reshape(w * h, d)
|
16 |
+
|
17 |
+
return KMeans(n_clusters=n_clusters).fit(pixels)
|
18 |
+
|
19 |
+
|
20 |
+
def sort_color_clusters(k_means: KMeans):
|
21 |
+
return sorted(k_means.cluster_centers_, key=get_hsv_value)
|
22 |
+
|
23 |
+
|
24 |
+
def iter_color_shades(k_means: KMeans, shades: tuple[float, ...]):
|
25 |
+
cluster_centers = sort_color_clusters(k_means)
|
26 |
+
|
27 |
+
for delta, cluster_center in itertools.product(shades, cluster_centers):
|
28 |
+
yield add_hsv_saturation(cluster_center, delta)
|
29 |
+
|
30 |
+
|
31 |
+
def generate_palette_image(k_means: KMeans, size=40, shades=(0.0,)):
|
32 |
+
num_cluster_centers = len(k_means.cluster_centers_)
|
33 |
+
image = Image.new("RGB", (num_cluster_centers * size, len(shades) * size))
|
34 |
+
|
35 |
+
for i, color in enumerate(iter_color_shades(k_means, shades)):
|
36 |
+
color = tuple(map(int, color))
|
37 |
+
part = Image.new("RGB", (size, size), color)
|
38 |
+
position = (i % num_cluster_centers * size, i // num_cluster_centers * size)
|
39 |
+
image.paste(part, position)
|
40 |
+
|
41 |
+
return image
|
myapp/palette_demo.py
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from contextlib import ExitStack
|
2 |
+
|
3 |
+
import gradio as gr
|
4 |
+
import numpy as np
|
5 |
+
|
6 |
+
from myapp.colorutils import array_to_hex
|
7 |
+
from myapp.palette import extract_color_clusters, iter_color_shades
|
8 |
+
|
9 |
+
with gr.Blocks() as demo:
|
10 |
+
image = gr.Image("static/vulture.webp")
|
11 |
+
n_colors = gr.Slider(1, 16, 4, step=1)
|
12 |
+
button = gr.Button()
|
13 |
+
|
14 |
+
@gr.render(inputs=[image, n_colors])
|
15 |
+
def render_palette(image_array: np.ndarray, n_clusers: int):
|
16 |
+
model = extract_color_clusters(image_array, n_clusers)
|
17 |
+
cluster_shades = iter_color_shades(model, (0, 0.2, 0.4, 0.6))
|
18 |
+
|
19 |
+
with ExitStack() as stack:
|
20 |
+
for i, cluster in enumerate(cluster_shades):
|
21 |
+
if i % n_clusers == 0:
|
22 |
+
stack.pop_all().close()
|
23 |
+
stack.enter_context(gr.Group())
|
24 |
+
stack.enter_context(gr.Row(variant="compact"))
|
25 |
+
|
26 |
+
gr.ColorPicker(array_to_hex(cluster), container=False)
|
27 |
+
|
28 |
+
|
29 |
+
if __name__ == "__main__":
|
30 |
+
demo.launch()
|
myapp/params.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Any
|
2 |
+
|
3 |
+
import click
|
4 |
+
from PIL import Image
|
5 |
+
|
6 |
+
|
7 |
+
class ImageParamType(click.ParamType):
|
8 |
+
name = "image"
|
9 |
+
|
10 |
+
def convert(
|
11 |
+
self, value: Any, param: click.Parameter | None, ctx: click.Context | None
|
12 |
+
) -> Any:
|
13 |
+
if value is None or isinstance(value, Image.Image):
|
14 |
+
return value
|
15 |
+
|
16 |
+
try:
|
17 |
+
return Image.open(value)
|
18 |
+
except OSError as e:
|
19 |
+
self.fail(str(e))
|
myapp/static/example.webp
ADDED
![]() |
myapp/static/vulture.webp
ADDED
![]() |
pyproject.toml
CHANGED
@@ -8,6 +8,7 @@ dependencies = [
|
|
8 |
"gradio>=5.14.0",
|
9 |
"huggingface-hub>=0.27.1",
|
10 |
"qrcode-artistic>=3.0.2",
|
|
|
11 |
"segno>=1.6.1",
|
12 |
]
|
13 |
|
@@ -19,3 +20,6 @@ develop = [
|
|
19 |
|
20 |
[tool.setuptools.packages.find]
|
21 |
include = ["myapp"]
|
|
|
|
|
|
|
|
8 |
"gradio>=5.14.0",
|
9 |
"huggingface-hub>=0.27.1",
|
10 |
"qrcode-artistic>=3.0.2",
|
11 |
+
"scikit-learn>=1.6.1",
|
12 |
"segno>=1.6.1",
|
13 |
]
|
14 |
|
|
|
20 |
|
21 |
[tool.setuptools.packages.find]
|
22 |
include = ["myapp"]
|
23 |
+
|
24 |
+
[project.scripts]
|
25 |
+
myapp = "myapp.cli:cli"
|
requirements.txt
CHANGED
@@ -57,6 +57,8 @@ idna==3.10
|
|
57 |
# requests
|
58 |
jinja2==3.1.5
|
59 |
# via gradio
|
|
|
|
|
60 |
markdown-it-py==3.0.0
|
61 |
# via rich
|
62 |
markupsafe==2.1.5
|
@@ -69,6 +71,8 @@ numpy==2.2.2
|
|
69 |
# via
|
70 |
# gradio
|
71 |
# pandas
|
|
|
|
|
72 |
orjson==3.10.15
|
73 |
# via gradio
|
74 |
packaging==24.2
|
@@ -112,6 +116,10 @@ ruff==0.9.4
|
|
112 |
# via gradio
|
113 |
safehttpx==0.1.6
|
114 |
# via gradio
|
|
|
|
|
|
|
|
|
115 |
segno==1.6.1
|
116 |
# via
|
117 |
# myapp (pyproject.toml)
|
@@ -128,6 +136,8 @@ starlette==0.41.3
|
|
128 |
# via
|
129 |
# fastapi
|
130 |
# gradio
|
|
|
|
|
131 |
tomlkit==0.13.2
|
132 |
# via gradio
|
133 |
tqdm==4.67.1
|
|
|
57 |
# requests
|
58 |
jinja2==3.1.5
|
59 |
# via gradio
|
60 |
+
joblib==1.4.2
|
61 |
+
# via scikit-learn
|
62 |
markdown-it-py==3.0.0
|
63 |
# via rich
|
64 |
markupsafe==2.1.5
|
|
|
71 |
# via
|
72 |
# gradio
|
73 |
# pandas
|
74 |
+
# scikit-learn
|
75 |
+
# scipy
|
76 |
orjson==3.10.15
|
77 |
# via gradio
|
78 |
packaging==24.2
|
|
|
116 |
# via gradio
|
117 |
safehttpx==0.1.6
|
118 |
# via gradio
|
119 |
+
scikit-learn==1.6.1
|
120 |
+
# via myapp (pyproject.toml)
|
121 |
+
scipy==1.15.1
|
122 |
+
# via scikit-learn
|
123 |
segno==1.6.1
|
124 |
# via
|
125 |
# myapp (pyproject.toml)
|
|
|
136 |
# via
|
137 |
# fastapi
|
138 |
# gradio
|
139 |
+
threadpoolctl==3.5.0
|
140 |
+
# via scikit-learn
|
141 |
tomlkit==0.13.2
|
142 |
# via gradio
|
143 |
tqdm==4.67.1
|
uv.lock
CHANGED
@@ -386,6 +386,15 @@ wheels = [
|
|
386 |
{ url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 },
|
387 |
]
|
388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
389 |
[[package]]
|
390 |
name = "markdown-it-py"
|
391 |
version = "3.0.0"
|
@@ -445,6 +454,7 @@ dependencies = [
|
|
445 |
{ name = "gradio" },
|
446 |
{ name = "huggingface-hub" },
|
447 |
{ name = "qrcode-artistic" },
|
|
|
448 |
{ name = "segno" },
|
449 |
]
|
450 |
|
@@ -461,6 +471,7 @@ requires-dist = [
|
|
461 |
{ name = "ipdb", marker = "extra == 'develop'", specifier = ">=0.13.13" },
|
462 |
{ name = "python-dotenv", marker = "extra == 'develop'", specifier = ">=1.0.1" },
|
463 |
{ name = "qrcode-artistic", specifier = ">=3.0.2" },
|
|
|
464 |
{ name = "segno", specifier = ">=1.6.1" },
|
465 |
]
|
466 |
|
@@ -882,6 +893,68 @@ wheels = [
|
|
882 |
{ url = "https://files.pythonhosted.org/packages/4d/c0/1108ad9f01567f66b3154063605b350b69c3c9366732e09e45f9fd0d1deb/safehttpx-0.1.6-py3-none-any.whl", hash = "sha256:407cff0b410b071623087c63dd2080c3b44dc076888d8c5823c00d1e58cb381c", size = 8692 },
|
883 |
]
|
884 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
885 |
[[package]]
|
886 |
name = "segno"
|
887 |
version = "1.6.1"
|
@@ -953,6 +1026,15 @@ wheels = [
|
|
953 |
{ url = "https://files.pythonhosted.org/packages/d9/61/f2b52e107b1fc8944b33ef56bf6ac4ebbe16d91b94d2b87ce013bf63fb84/starlette-0.45.3-py3-none-any.whl", hash = "sha256:dfb6d332576f136ec740296c7e8bb8c8a7125044e7c6da30744718880cdd059d", size = 71507 },
|
954 |
]
|
955 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
956 |
[[package]]
|
957 |
name = "tomlkit"
|
958 |
version = "0.13.2"
|
|
|
386 |
{ url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 },
|
387 |
]
|
388 |
|
389 |
+
[[package]]
|
390 |
+
name = "joblib"
|
391 |
+
version = "1.4.2"
|
392 |
+
source = { registry = "https://pypi.org/simple" }
|
393 |
+
sdist = { url = "https://files.pythonhosted.org/packages/64/33/60135848598c076ce4b231e1b1895170f45fbcaeaa2c9d5e38b04db70c35/joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e", size = 2116621 }
|
394 |
+
wheels = [
|
395 |
+
{ url = "https://files.pythonhosted.org/packages/91/29/df4b9b42f2be0b623cbd5e2140cafcaa2bef0759a00b7b70104dcfe2fb51/joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6", size = 301817 },
|
396 |
+
]
|
397 |
+
|
398 |
[[package]]
|
399 |
name = "markdown-it-py"
|
400 |
version = "3.0.0"
|
|
|
454 |
{ name = "gradio" },
|
455 |
{ name = "huggingface-hub" },
|
456 |
{ name = "qrcode-artistic" },
|
457 |
+
{ name = "scikit-learn" },
|
458 |
{ name = "segno" },
|
459 |
]
|
460 |
|
|
|
471 |
{ name = "ipdb", marker = "extra == 'develop'", specifier = ">=0.13.13" },
|
472 |
{ name = "python-dotenv", marker = "extra == 'develop'", specifier = ">=1.0.1" },
|
473 |
{ name = "qrcode-artistic", specifier = ">=3.0.2" },
|
474 |
+
{ name = "scikit-learn", specifier = ">=1.6.1" },
|
475 |
{ name = "segno", specifier = ">=1.6.1" },
|
476 |
]
|
477 |
|
|
|
893 |
{ url = "https://files.pythonhosted.org/packages/4d/c0/1108ad9f01567f66b3154063605b350b69c3c9366732e09e45f9fd0d1deb/safehttpx-0.1.6-py3-none-any.whl", hash = "sha256:407cff0b410b071623087c63dd2080c3b44dc076888d8c5823c00d1e58cb381c", size = 8692 },
|
894 |
]
|
895 |
|
896 |
+
[[package]]
|
897 |
+
name = "scikit-learn"
|
898 |
+
version = "1.6.1"
|
899 |
+
source = { registry = "https://pypi.org/simple" }
|
900 |
+
dependencies = [
|
901 |
+
{ name = "joblib" },
|
902 |
+
{ name = "numpy" },
|
903 |
+
{ name = "scipy" },
|
904 |
+
{ name = "threadpoolctl" },
|
905 |
+
]
|
906 |
+
sdist = { url = "https://files.pythonhosted.org/packages/9e/a5/4ae3b3a0755f7b35a280ac90b28817d1f380318973cff14075ab41ef50d9/scikit_learn-1.6.1.tar.gz", hash = "sha256:b4fc2525eca2c69a59260f583c56a7557c6ccdf8deafdba6e060f94c1c59738e", size = 7068312 }
|
907 |
+
wheels = [
|
908 |
+
{ url = "https://files.pythonhosted.org/packages/0a/18/c797c9b8c10380d05616db3bfb48e2a3358c767affd0857d56c2eb501caa/scikit_learn-1.6.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:926f207c804104677af4857b2c609940b743d04c4c35ce0ddc8ff4f053cddc1b", size = 12104516 },
|
909 |
+
{ url = "https://files.pythonhosted.org/packages/c4/b7/2e35f8e289ab70108f8cbb2e7a2208f0575dc704749721286519dcf35f6f/scikit_learn-1.6.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2c2cae262064e6a9b77eee1c8e768fc46aa0b8338c6a8297b9b6759720ec0ff2", size = 11167837 },
|
910 |
+
{ url = "https://files.pythonhosted.org/packages/a4/f6/ff7beaeb644bcad72bcfd5a03ff36d32ee4e53a8b29a639f11bcb65d06cd/scikit_learn-1.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1061b7c028a8663fb9a1a1baf9317b64a257fcb036dae5c8752b2abef31d136f", size = 12253728 },
|
911 |
+
{ url = "https://files.pythonhosted.org/packages/29/7a/8bce8968883e9465de20be15542f4c7e221952441727c4dad24d534c6d99/scikit_learn-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e69fab4ebfc9c9b580a7a80111b43d214ab06250f8a7ef590a4edf72464dd86", size = 13147700 },
|
912 |
+
{ url = "https://files.pythonhosted.org/packages/62/27/585859e72e117fe861c2079bcba35591a84f801e21bc1ab85bce6ce60305/scikit_learn-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:70b1d7e85b1c96383f872a519b3375f92f14731e279a7b4c6cfd650cf5dffc52", size = 11110613 },
|
913 |
+
{ url = "https://files.pythonhosted.org/packages/2e/59/8eb1872ca87009bdcdb7f3cdc679ad557b992c12f4b61f9250659e592c63/scikit_learn-1.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ffa1e9e25b3d93990e74a4be2c2fc61ee5af85811562f1288d5d055880c4322", size = 12010001 },
|
914 |
+
{ url = "https://files.pythonhosted.org/packages/9d/05/f2fc4effc5b32e525408524c982c468c29d22f828834f0625c5ef3d601be/scikit_learn-1.6.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:dc5cf3d68c5a20ad6d571584c0750ec641cc46aeef1c1507be51300e6003a7e1", size = 11096360 },
|
915 |
+
{ url = "https://files.pythonhosted.org/packages/c8/e4/4195d52cf4f113573fb8ebc44ed5a81bd511a92c0228889125fac2f4c3d1/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c06beb2e839ecc641366000ca84f3cf6fa9faa1777e29cf0c04be6e4d096a348", size = 12209004 },
|
916 |
+
{ url = "https://files.pythonhosted.org/packages/94/be/47e16cdd1e7fcf97d95b3cb08bde1abb13e627861af427a3651fcb80b517/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8ca8cb270fee8f1f76fa9bfd5c3507d60c6438bbee5687f81042e2bb98e5a97", size = 13171776 },
|
917 |
+
{ url = "https://files.pythonhosted.org/packages/34/b0/ca92b90859070a1487827dbc672f998da95ce83edce1270fc23f96f1f61a/scikit_learn-1.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:7a1c43c8ec9fde528d664d947dc4c0789be4077a3647f232869f41d9bf50e0fb", size = 11071865 },
|
918 |
+
{ url = "https://files.pythonhosted.org/packages/12/ae/993b0fb24a356e71e9a894e42b8a9eec528d4c70217353a1cd7a48bc25d4/scikit_learn-1.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a17c1dea1d56dcda2fac315712f3651a1fea86565b64b48fa1bc090249cbf236", size = 11955804 },
|
919 |
+
{ url = "https://files.pythonhosted.org/packages/d6/54/32fa2ee591af44507eac86406fa6bba968d1eb22831494470d0a2e4a1eb1/scikit_learn-1.6.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6a7aa5f9908f0f28f4edaa6963c0a6183f1911e63a69aa03782f0d924c830a35", size = 11100530 },
|
920 |
+
{ url = "https://files.pythonhosted.org/packages/3f/58/55856da1adec655bdce77b502e94a267bf40a8c0b89f8622837f89503b5a/scikit_learn-1.6.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0650e730afb87402baa88afbf31c07b84c98272622aaba002559b614600ca691", size = 12433852 },
|
921 |
+
{ url = "https://files.pythonhosted.org/packages/ff/4f/c83853af13901a574f8f13b645467285a48940f185b690936bb700a50863/scikit_learn-1.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:3f59fe08dc03ea158605170eb52b22a105f238a5d512c4470ddeca71feae8e5f", size = 11337256 },
|
922 |
+
]
|
923 |
+
|
924 |
+
[[package]]
|
925 |
+
name = "scipy"
|
926 |
+
version = "1.15.1"
|
927 |
+
source = { registry = "https://pypi.org/simple" }
|
928 |
+
dependencies = [
|
929 |
+
{ name = "numpy" },
|
930 |
+
]
|
931 |
+
sdist = { url = "https://files.pythonhosted.org/packages/76/c6/8eb0654ba0c7d0bb1bf67bf8fbace101a8e4f250f7722371105e8b6f68fc/scipy-1.15.1.tar.gz", hash = "sha256:033a75ddad1463970c96a88063a1df87ccfddd526437136b6ee81ff0312ebdf6", size = 59407493 }
|
932 |
+
wheels = [
|
933 |
+
{ url = "https://files.pythonhosted.org/packages/d8/6e/a9c42d0d39e09ed7fd203d0ac17adfea759cba61ab457671fe66e523dbec/scipy-1.15.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c09aa9d90f3500ea4c9b393ee96f96b0ccb27f2f350d09a47f533293c78ea776", size = 41478318 },
|
934 |
+
{ url = "https://files.pythonhosted.org/packages/04/ee/e3e535c81828618878a7433992fecc92fa4df79393f31a8fea1d05615091/scipy-1.15.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0ac102ce99934b162914b1e4a6b94ca7da0f4058b6d6fd65b0cef330c0f3346f", size = 32596696 },
|
935 |
+
{ url = "https://files.pythonhosted.org/packages/c4/5e/b1b0124be8e76f87115f16b8915003eec4b7060298117715baf13f51942c/scipy-1.15.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:09c52320c42d7f5c7748b69e9f0389266fd4f82cf34c38485c14ee976cb8cb04", size = 24870366 },
|
936 |
+
{ url = "https://files.pythonhosted.org/packages/14/36/c00cb73eefda85946172c27913ab995c6ad4eee00fa4f007572e8c50cd51/scipy-1.15.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:cdde8414154054763b42b74fe8ce89d7f3d17a7ac5dd77204f0e142cdc9239e9", size = 28007461 },
|
937 |
+
{ url = "https://files.pythonhosted.org/packages/68/94/aff5c51b3799349a9d1e67a056772a0f8a47db371e83b498d43467806557/scipy-1.15.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c9d8fc81d6a3b6844235e6fd175ee1d4c060163905a2becce8e74cb0d7554ce", size = 38068174 },
|
938 |
+
{ url = "https://files.pythonhosted.org/packages/b0/3c/0de11ca154e24a57b579fb648151d901326d3102115bc4f9a7a86526ce54/scipy-1.15.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fb57b30f0017d4afa5fe5f5b150b8f807618819287c21cbe51130de7ccdaed2", size = 40249869 },
|
939 |
+
{ url = "https://files.pythonhosted.org/packages/15/09/472e8d0a6b33199d1bb95e49bedcabc0976c3724edd9b0ef7602ccacf41e/scipy-1.15.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:491d57fe89927fa1aafbe260f4cfa5ffa20ab9f1435025045a5315006a91b8f5", size = 42629068 },
|
940 |
+
{ url = "https://files.pythonhosted.org/packages/ff/ba/31c7a8131152822b3a2cdeba76398ffb404d81d640de98287d236da90c49/scipy-1.15.1-cp312-cp312-win_amd64.whl", hash = "sha256:900f3fa3db87257510f011c292a5779eb627043dd89731b9c461cd16ef76ab3d", size = 43621992 },
|
941 |
+
{ url = "https://files.pythonhosted.org/packages/2b/bf/dd68965a4c5138a630eeed0baec9ae96e5d598887835bdde96cdd2fe4780/scipy-1.15.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:100193bb72fbff37dbd0bf14322314fc7cbe08b7ff3137f11a34d06dc0ee6b85", size = 41441136 },
|
942 |
+
{ url = "https://files.pythonhosted.org/packages/ef/5e/4928581312922d7e4d416d74c416a660addec4dd5ea185401df2269ba5a0/scipy-1.15.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:2114a08daec64980e4b4cbdf5bee90935af66d750146b1d2feb0d3ac30613692", size = 32533699 },
|
943 |
+
{ url = "https://files.pythonhosted.org/packages/32/90/03f99c43041852837686898c66767787cd41c5843d7a1509c39ffef683e9/scipy-1.15.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:6b3e71893c6687fc5e29208d518900c24ea372a862854c9888368c0b267387ab", size = 24807289 },
|
944 |
+
{ url = "https://files.pythonhosted.org/packages/9d/52/bfe82b42ae112eaba1af2f3e556275b8727d55ac6e4932e7aef337a9d9d4/scipy-1.15.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:837299eec3d19b7e042923448d17d95a86e43941104d33f00da7e31a0f715d3c", size = 27929844 },
|
945 |
+
{ url = "https://files.pythonhosted.org/packages/f6/77/54ff610bad600462c313326acdb035783accc6a3d5f566d22757ad297564/scipy-1.15.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82add84e8a9fb12af5c2c1a3a3f1cb51849d27a580cb9e6bd66226195142be6e", size = 38031272 },
|
946 |
+
{ url = "https://files.pythonhosted.org/packages/f1/26/98585cbf04c7cf503d7eb0a1966df8a268154b5d923c5fe0c1ed13154c49/scipy-1.15.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070d10654f0cb6abd295bc96c12656f948e623ec5f9a4eab0ddb1466c000716e", size = 40210217 },
|
947 |
+
{ url = "https://files.pythonhosted.org/packages/fd/3f/3d2285eb6fece8bc5dbb2f9f94d61157d61d155e854fd5fea825b8218f12/scipy-1.15.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:55cc79ce4085c702ac31e49b1e69b27ef41111f22beafb9b49fea67142b696c4", size = 42587785 },
|
948 |
+
{ url = "https://files.pythonhosted.org/packages/48/7d/5b5251984bf0160d6533695a74a5fddb1fa36edd6f26ffa8c871fbd4782a/scipy-1.15.1-cp313-cp313-win_amd64.whl", hash = "sha256:c352c1b6d7cac452534517e022f8f7b8d139cd9f27e6fbd9f3cbd0bfd39f5bef", size = 43640439 },
|
949 |
+
{ url = "https://files.pythonhosted.org/packages/e7/b8/0e092f592d280496de52e152582030f8a270b194f87f890e1a97c5599b81/scipy-1.15.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0458839c9f873062db69a03de9a9765ae2e694352c76a16be44f93ea45c28d2b", size = 41619862 },
|
950 |
+
{ url = "https://files.pythonhosted.org/packages/f6/19/0b6e1173aba4db9e0b7aa27fe45019857fb90d6904038b83927cbe0a6c1d/scipy-1.15.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:af0b61c1de46d0565b4b39c6417373304c1d4f5220004058bdad3061c9fa8a95", size = 32610387 },
|
951 |
+
{ url = "https://files.pythonhosted.org/packages/e7/02/754aae3bd1fa0f2479ade3cfdf1732ecd6b05853f63eee6066a32684563a/scipy-1.15.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:71ba9a76c2390eca6e359be81a3e879614af3a71dfdabb96d1d7ab33da6f2364", size = 24883814 },
|
952 |
+
{ url = "https://files.pythonhosted.org/packages/1f/ac/d7906201604a2ea3b143bb0de51b3966f66441ba50b7dc182c4505b3edf9/scipy-1.15.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:14eaa373c89eaf553be73c3affb11ec6c37493b7eaaf31cf9ac5dffae700c2e0", size = 27944865 },
|
953 |
+
{ url = "https://files.pythonhosted.org/packages/84/9d/8f539002b5e203723af6a6f513a45e0a7671e9dabeedb08f417ac17e4edc/scipy-1.15.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f735bc41bd1c792c96bc426dece66c8723283695f02df61dcc4d0a707a42fc54", size = 39883261 },
|
954 |
+
{ url = "https://files.pythonhosted.org/packages/97/c0/62fd3bab828bcccc9b864c5997645a3b86372a35941cdaf677565c25c98d/scipy-1.15.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2722a021a7929d21168830790202a75dbb20b468a8133c74a2c0230c72626b6c", size = 42093299 },
|
955 |
+
{ url = "https://files.pythonhosted.org/packages/e4/1f/5d46a8d94e9f6d2c913cbb109e57e7eed914de38ea99e2c4d69a9fc93140/scipy-1.15.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bc7136626261ac1ed988dca56cfc4ab5180f75e0ee52e58f1e6aa74b5f3eacd5", size = 43181730 },
|
956 |
+
]
|
957 |
+
|
958 |
[[package]]
|
959 |
name = "segno"
|
960 |
version = "1.6.1"
|
|
|
1026 |
{ url = "https://files.pythonhosted.org/packages/d9/61/f2b52e107b1fc8944b33ef56bf6ac4ebbe16d91b94d2b87ce013bf63fb84/starlette-0.45.3-py3-none-any.whl", hash = "sha256:dfb6d332576f136ec740296c7e8bb8c8a7125044e7c6da30744718880cdd059d", size = 71507 },
|
1027 |
]
|
1028 |
|
1029 |
+
[[package]]
|
1030 |
+
name = "threadpoolctl"
|
1031 |
+
version = "3.5.0"
|
1032 |
+
source = { registry = "https://pypi.org/simple" }
|
1033 |
+
sdist = { url = "https://files.pythonhosted.org/packages/bd/55/b5148dcbf72f5cde221f8bfe3b6a540da7aa1842f6b491ad979a6c8b84af/threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107", size = 41936 }
|
1034 |
+
wheels = [
|
1035 |
+
{ url = "https://files.pythonhosted.org/packages/4b/2c/ffbf7a134b9ab11a67b0cf0726453cedd9c5043a4fe7a35d1cefa9a1bcfb/threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467", size = 18414 },
|
1036 |
+
]
|
1037 |
+
|
1038 |
[[package]]
|
1039 |
name = "tomlkit"
|
1040 |
version = "0.13.2"
|