Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files- .github/workflows/python_app.yaml +39 -0
- .github/workflows/update_space.yml +7 -3
- .pytest_cache/.gitignore +2 -0
- .pytest_cache/CACHEDIR.TAG +4 -0
- .pytest_cache/README.md +8 -0
- .pytest_cache/v/cache/nodeids +8 -0
- pyproject.toml +1 -0
- requirements.txt +10 -1
- tests/test_graphics_tools.py +34 -0
- tests/test_tools.py +41 -0
.github/workflows/python_app.yaml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
| 2 |
+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
|
| 3 |
+
|
| 4 |
+
name: Python application
|
| 5 |
+
|
| 6 |
+
on:
|
| 7 |
+
push:
|
| 8 |
+
branches: [ "master" ]
|
| 9 |
+
pull_request:
|
| 10 |
+
branches: [ "master" ]
|
| 11 |
+
|
| 12 |
+
permissions:
|
| 13 |
+
contents: read
|
| 14 |
+
|
| 15 |
+
jobs:
|
| 16 |
+
build:
|
| 17 |
+
|
| 18 |
+
runs-on: ubuntu-latest
|
| 19 |
+
|
| 20 |
+
steps:
|
| 21 |
+
- uses: actions/checkout@v4
|
| 22 |
+
- name: Set up Python 3.12
|
| 23 |
+
uses: actions/setup-python@v3
|
| 24 |
+
with:
|
| 25 |
+
python-version: "3.12"
|
| 26 |
+
- name: Install dependencies
|
| 27 |
+
run: |
|
| 28 |
+
python -m pip install --upgrade pip
|
| 29 |
+
pip install flake8 pytest
|
| 30 |
+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
| 31 |
+
- name: Lint with flake8
|
| 32 |
+
run: |
|
| 33 |
+
# stop the build if there are Python syntax errors or undefined names
|
| 34 |
+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
| 35 |
+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
| 36 |
+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
| 37 |
+
- name: Test with pytest
|
| 38 |
+
run: |
|
| 39 |
+
pytest
|
.github/workflows/update_space.yml
CHANGED
|
@@ -16,13 +16,17 @@ jobs:
|
|
| 16 |
- name: Set up Python
|
| 17 |
uses: actions/setup-python@v2
|
| 18 |
with:
|
| 19 |
-
python-version: '3.
|
| 20 |
|
| 21 |
- name: Install Gradio
|
| 22 |
run: python -m pip install gradio
|
| 23 |
|
| 24 |
-
|
| 25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
- name: Log in to Hugging Face
|
| 28 |
run: |
|
|
|
|
| 16 |
- name: Set up Python
|
| 17 |
uses: actions/setup-python@v2
|
| 18 |
with:
|
| 19 |
+
python-version: '3.12'
|
| 20 |
|
| 21 |
- name: Install Gradio
|
| 22 |
run: python -m pip install gradio
|
| 23 |
|
| 24 |
+
- name: Install dependencies
|
| 25 |
+
run: |
|
| 26 |
+
python -m pip install -r requirements.txt
|
| 27 |
+
|
| 28 |
+
- name: Run tests
|
| 29 |
+
run: pytest --maxfail=3 --disable-warnings -q
|
| 30 |
|
| 31 |
- name: Log in to Hugging Face
|
| 32 |
run: |
|
.pytest_cache/.gitignore
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Created by pytest automatically.
|
| 2 |
+
*
|
.pytest_cache/CACHEDIR.TAG
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Signature: 8a477f597d28d172789f06886806bc55
|
| 2 |
+
# This file is a cache directory tag created by pytest.
|
| 3 |
+
# For information about cache directory tags, see:
|
| 4 |
+
# https://bford.info/cachedir/spec.html
|
.pytest_cache/README.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# pytest cache directory #
|
| 2 |
+
|
| 3 |
+
This directory contains data from the pytest's cache plugin,
|
| 4 |
+
which provides the `--lf` and `--ff` options, as well as the `cache` fixture.
|
| 5 |
+
|
| 6 |
+
**Do not** commit this to version control.
|
| 7 |
+
|
| 8 |
+
See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information.
|
.pytest_cache/v/cache/nodeids
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
"tests/test_graphics_tools.py::test_compute_difference",
|
| 3 |
+
"tests/test_graphics_tools.py::test_find_closest_color_idx",
|
| 4 |
+
"tests/test_graphics_tools.py::test_replace_colors_by_template",
|
| 5 |
+
"tests/test_tools.py::test_create_color_palette_square_grid",
|
| 6 |
+
"tests/test_tools.py::test_create_palette_image",
|
| 7 |
+
"tests/test_tools.py::test_extract_color_palette_basic"
|
| 8 |
+
]
|
pyproject.toml
CHANGED
|
@@ -10,4 +10,5 @@ dependencies = [
|
|
| 10 |
"openai-agents>=0.0.16",
|
| 11 |
"pillow>=11.2.1",
|
| 12 |
"scikit-learn>=1.6.1",
|
|
|
|
| 13 |
]
|
|
|
|
| 10 |
"openai-agents>=0.0.16",
|
| 11 |
"pillow>=11.2.1",
|
| 12 |
"scikit-learn>=1.6.1",
|
| 13 |
+
"pytest>=8.4.0",
|
| 14 |
]
|
requirements.txt
CHANGED
|
@@ -71,6 +71,8 @@ idna==3.10
|
|
| 71 |
# anyio
|
| 72 |
# httpx
|
| 73 |
# requests
|
|
|
|
|
|
|
| 74 |
jinja2==3.1.6
|
| 75 |
# via gradio
|
| 76 |
jiter==0.10.0
|
|
@@ -106,12 +108,15 @@ packaging==25.0
|
|
| 106 |
# gradio
|
| 107 |
# gradio-client
|
| 108 |
# huggingface-hub
|
|
|
|
| 109 |
pandas==2.2.3
|
| 110 |
# via gradio
|
| 111 |
pillow==11.2.1
|
| 112 |
# via
|
| 113 |
# brandsmith-gradio (pyproject.toml)
|
| 114 |
# gradio
|
|
|
|
|
|
|
| 115 |
pydantic==2.11.5
|
| 116 |
# via
|
| 117 |
# fastapi
|
|
@@ -127,7 +132,11 @@ pydantic-settings==2.9.1
|
|
| 127 |
pydub==0.25.1
|
| 128 |
# via gradio
|
| 129 |
pygments==2.19.1
|
| 130 |
-
# via
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
python-dateutil==2.9.0.post0
|
| 132 |
# via pandas
|
| 133 |
python-dotenv==1.1.0
|
|
|
|
| 71 |
# anyio
|
| 72 |
# httpx
|
| 73 |
# requests
|
| 74 |
+
iniconfig==2.1.0
|
| 75 |
+
# via pytest
|
| 76 |
jinja2==3.1.6
|
| 77 |
# via gradio
|
| 78 |
jiter==0.10.0
|
|
|
|
| 108 |
# gradio
|
| 109 |
# gradio-client
|
| 110 |
# huggingface-hub
|
| 111 |
+
# pytest
|
| 112 |
pandas==2.2.3
|
| 113 |
# via gradio
|
| 114 |
pillow==11.2.1
|
| 115 |
# via
|
| 116 |
# brandsmith-gradio (pyproject.toml)
|
| 117 |
# gradio
|
| 118 |
+
pluggy==1.6.0
|
| 119 |
+
# via pytest
|
| 120 |
pydantic==2.11.5
|
| 121 |
# via
|
| 122 |
# fastapi
|
|
|
|
| 132 |
pydub==0.25.1
|
| 133 |
# via gradio
|
| 134 |
pygments==2.19.1
|
| 135 |
+
# via
|
| 136 |
+
# pytest
|
| 137 |
+
# rich
|
| 138 |
+
pytest==8.4.0
|
| 139 |
+
# via brandsmith-gradio (pyproject.toml)
|
| 140 |
python-dateutil==2.9.0.post0
|
| 141 |
# via pandas
|
| 142 |
python-dotenv==1.1.0
|
tests/test_graphics_tools.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
import os
|
| 3 |
+
import pytest
|
| 4 |
+
from PIL import Image
|
| 5 |
+
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../src')))
|
| 6 |
+
import graphics_tools
|
| 7 |
+
|
| 8 |
+
class DummyImageTemplate:
|
| 9 |
+
def __init__(self, image, colors):
|
| 10 |
+
self.image = image
|
| 11 |
+
self.colors = colors
|
| 12 |
+
|
| 13 |
+
def test_find_closest_color_idx():
|
| 14 |
+
color = (100, 100, 100)
|
| 15 |
+
template_colors = [(0, 0, 0), (255, 255, 255), (110, 110, 110)]
|
| 16 |
+
idx = graphics_tools.find_closest_color_idx(color, template_colors)
|
| 17 |
+
assert idx == 2
|
| 18 |
+
|
| 19 |
+
def test_compute_difference():
|
| 20 |
+
color1 = (10, 20, 30)
|
| 21 |
+
color2 = (20, 10, 40)
|
| 22 |
+
diff = graphics_tools.compute_difference(color1, color2)
|
| 23 |
+
assert diff == 30
|
| 24 |
+
|
| 25 |
+
def test_replace_colors_by_template(tmp_path):
|
| 26 |
+
# Create a dummy image
|
| 27 |
+
img = Image.new('RGB', (2, 2), (100, 100, 100))
|
| 28 |
+
img_path = tmp_path / 'dummy.png'
|
| 29 |
+
img.save(img_path)
|
| 30 |
+
colors = [(100, 100, 100), (200, 200, 200)]
|
| 31 |
+
template = DummyImageTemplate(str(img_path), colors)
|
| 32 |
+
target_colors = [(1, 2, 3), (4, 5, 6)]
|
| 33 |
+
out_img = graphics_tools.replace_colors_by_template(template, target_colors)
|
| 34 |
+
assert isinstance(out_img, Image.Image)
|
tests/test_tools.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
import os
|
| 3 |
+
import pytest
|
| 4 |
+
import numpy as np
|
| 5 |
+
from PIL import Image
|
| 6 |
+
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../src')))
|
| 7 |
+
import tools
|
| 8 |
+
from models import ColorPalette, ColorItem
|
| 9 |
+
|
| 10 |
+
class DummyColorItem:
|
| 11 |
+
def __init__(self, R, G, B, count):
|
| 12 |
+
self.R = R
|
| 13 |
+
self.G = G
|
| 14 |
+
self.B = B
|
| 15 |
+
self.count = count
|
| 16 |
+
|
| 17 |
+
class DummyColorPalette:
|
| 18 |
+
def __init__(self, colors):
|
| 19 |
+
self.colors = colors
|
| 20 |
+
|
| 21 |
+
def test_extract_color_palette_basic():
|
| 22 |
+
img = Image.new('RGBA', (10, 10), (255, 0, 0, 255))
|
| 23 |
+
palette = tools.extract_color_palette(img, 1)
|
| 24 |
+
assert hasattr(palette, 'colors')
|
| 25 |
+
assert len(palette.colors) == 1
|
| 26 |
+
assert palette.colors[0].R == 255
|
| 27 |
+
assert palette.colors[0].G == 0
|
| 28 |
+
assert palette.colors[0].B == 0
|
| 29 |
+
|
| 30 |
+
def test_create_color_palette_square_grid():
|
| 31 |
+
colors = [ColorItem(R=255, G=0, B=0, count=50), ColorItem(R=0, G=255, B=0, count=50)]
|
| 32 |
+
palette = ColorPalette(colors=colors)
|
| 33 |
+
img = tools.create_color_palette_square_grid(palette, total_pixels=100)
|
| 34 |
+
assert isinstance(img, Image.Image)
|
| 35 |
+
assert img.size[0] == img.size[1] # Should be square
|
| 36 |
+
|
| 37 |
+
def test_create_palette_image():
|
| 38 |
+
colors = [ColorItem(R=255, G=0, B=0, count=50), ColorItem(R=0, G=255, B=0, count=50)]
|
| 39 |
+
palette = ColorPalette(colors=colors)
|
| 40 |
+
img = tools.create_palette_image(palette)
|
| 41 |
+
assert isinstance(img, Image.Image)
|