Skip to content

Commit

Permalink
Merge branch 'master' into Segment-Anything
Browse files Browse the repository at this point in the history
  • Loading branch information
Wanghanying committed Sep 29, 2024
2 parents c18c7a8 + ff1cff6 commit b48a222
Show file tree
Hide file tree
Showing 82 changed files with 5,894 additions and 1,106 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/workflow-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
with:
repository: comfyanonymous/ComfyUI
path: ComfyUI
ref: v0.0.4
ref: v0.2.1

- name: Checkout plugin repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -87,6 +87,7 @@ jobs:
cd custom_nodes/BizyAir
echo "Current directory: $(pwd)"
python3 tests/write_api_ini_file.py
python3 tests/test_examples.py
env:
BIZYAIR_KEY: ${{ secrets.BIZYAIR_KEY }}
Expand All @@ -99,6 +100,7 @@ jobs:
Start-Process -FilePath "python3" -ArgumentList "main.py --port 8188 --cpu" -NoNewWindow
cd custom_nodes/BizyAir
Write-Output "Current directory: $(Get-Location)"
python3 tests/write_api_ini_file.py
python3 tests/test_examples.py
env:
BIZYAIR_KEY: ${{ secrets.BIZYAIR_KEY }}
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ repos:
hooks:
- id: sort-imports
name: Sort imports
entry: python -m isort --profile black .
entry: python3 -m isort --profile black .
language: system
types: [python]
- id: format-code
name: Format code
entry: python -m black .
entry: python3 -m black .
language: system
types: [python]
- id: flake8-code-check
name: Code Quality Check
entry: python -m flake8 .
entry: python3 -m flake8 .
language: system
types: [python]

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# BizyAir

- [2024/09/19] 🌩️ BizyAir has updated the model upload feature, allowing the upload process to display a progress bar, and the size of the models uploaded is no longer restricted by ComfyUI. (https://siliconflow.github.io/BizyAir/model-host/introduce.html)
- [2024/09/06] 🌩️ BizyAir supports InstantID for SDXL now. [SDXL InstantID workflow](./examples/bizyair_sdxl_InstantID_basic.json)
- [2024/09/05] 🌩️ BizyAir supports users in running custom LoRA models, including SDXL and Flux LoRA. [How to upload and run custom model](https://siliconflow.github.io/BizyAir/model-host/introduce.html)
- [2024/08/23] 🌩️ BizyAir now support ultimateSDupscale nodes [upscale workflow](./examples/bizyair_ultimate_sd_upscale.json)
- [2024/08/14] 🌩️ BizyAir JoyCaption node has been released. [Try the example to recreate a image by JoyCaption and Flux](./examples/bizyair_flux_joycaption_img2img_workflow.json), thanks to [fancyfeast/joy-caption-pre-alpha](https://huggingface.co/spaces/fancyfeast/joy-caption-pre-alpha)
- [2024/08/05] 🌩️ FLUX.1-dev has been supported. [FLUX.1-dev Text to Image](./examples/bizyair_flux_dev_workflow.json), [FLUX.1-dev Image to Image](./examples/bizyair_flux_img2img_workflow.json)
Expand Down
15 changes: 15 additions & 0 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,18 @@ def update_mappings(module):
update_mappings(nodes_controlnet_aux)
update_mappings(nodes_controlnet_union_sdxl)
update_mappings(mzkolors)

# bizy_server
bizyair_adv_is_not_installed = False
try:
import crcmod
import oss2
except ImportError:
bizyair_adv_is_not_installed = True
print(
"\n\n\033[91m[BizyAir]\033[0m Please run"
" 'pip install -r requirements.txt' to install depencies for model host feature.\n\n"
)

if not bizyair_adv_is_not_installed:
import bizy_server
16 changes: 11 additions & 5 deletions auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from aiohttp import web

import bizyair
from bizyair.common import create_api_key_file, load_api_key
from bizyair.common import create_api_key_file, load_api_key, validate_api_key

API_KEY = None
html_file_path = Path(os.path.dirname(os.path.abspath(__file__))) / "set_api_key.html"
Expand All @@ -31,14 +31,20 @@ async def set_api_key(request):
data = await request.post()
api_key = data.get("api_key")
if api_key:
if not validate_api_key(api_key):
error_msg = "Wrong API key provided, please refer to cloud.siliconflow.cn to get the key"
print("set_api_key:", error_msg)
return web.Response(
text=error_msg,
status=400,
)
create_api_key_file(api_key)
API_KEY = api_key
bizyair.set_api_key(API_KEY)
bizyair.set_api_key(API_KEY, override=True)
print("Set the key sucessfully.")
return web.Response(text="ok")
else:
error_msg = (
"No token provided, please refer to cloud.siliconflow.cn to get the key"
)
error_msg = "No API key provided, please refer to cloud.siliconflow.cn to get the key"
print("set_api_key:", error_msg)
return web.Response(
text=error_msg,
Expand Down
6 changes: 4 additions & 2 deletions bizyair_example_menu.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"FLUX": {
"FLUX-schnell Text to Image(4 steps)": "bizyair_flux_schnell_workflow.json",
"FLUX-dev Text to Image": "bizyair_flux_dev_workflow.json",
"FLUX-dev Image to Image": "bizyair_flux_img2img_workflow.json"
"FLUX-dev Image to Image": "bizyair_flux_img2img_workflow.json",
"FLUX Simple Lora ": "bizyair_flux_simple_lora_workflow.json"
},
"ControlNet Union": {
"Generate an image from a line drawing": "bizyair_showcase_interior_design.json",
Expand All @@ -17,7 +18,8 @@
"Image to Image by BizyAir KSampler": "bizyair_showcase_ksampler_img2img.json",
"LoRA workflow by BizyAir KSampler": "bizyair_showcase_ksampler_lora.json",
"ControlNet workflow by BizyAir KSampler": "bizyair_showcase_ksampler_controlnet.json",
"IP Adapter workflow by BizyAir KSampler": "bizyair_showcase_ksampler_ipadapter.json"
"IP Adapter workflow by BizyAir KSampler": "bizyair_showcase_ksampler_ipadapter.json",
"InstantID Basic workflow by BizyAir KSampler": "bizyair_sdxl_InstantID_basic.json"
},
"Kolors": {
"Kolors Text to Image": "bizyair_kolors_txt2img.json",
Expand Down
3 changes: 3 additions & 0 deletions bizyair_extras/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from .nodes_comfyui_instantid import *
from .nodes_controlnet import *
from .nodes_image_utils import *
from .nodes_ipadapter_plus.nodes_ipadapter_plus import *
from .nodes_kolors_mz import *
from .nodes_testing_utils import *
Expand Down
164 changes: 164 additions & 0 deletions bizyair_extras/nodes_comfyui_instantid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
from bizyair import BizyAirBaseNode, data_types
from bizyair.path_utils import path_manager as folder_paths


class InstantIDModelLoader(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"instantid_file": (folder_paths.get_filename_list("instantid"),)
}
}

RETURN_TYPES = (data_types.INSTANTID,)
FUNCTION = "default_function"
CATEGORY = "InstantID"
NODE_DISPLAY_NAME = "Load InstantID Model"


class ApplyInstantID(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"instantid": (data_types.INSTANTID,),
"insightface": (data_types.FACEANALYSIS,),
"control_net": (data_types.CONTROL_NET,),
"image": ("IMAGE",),
"model": (data_types.MODEL,),
"positive": (data_types.CONDITIONING,),
"negative": (data_types.CONDITIONING,),
"weight": (
"FLOAT",
{
"default": 0.8,
"min": 0.0,
"max": 5.0,
"step": 0.01,
},
),
"start_at": (
"FLOAT",
{
"default": 0.0,
"min": 0.0,
"max": 1.0,
"step": 0.001,
},
),
"end_at": (
"FLOAT",
{
"default": 1.0,
"min": 0.0,
"max": 1.0,
"step": 0.001,
},
),
},
"optional": {
"image_kps": ("IMAGE",),
"mask": ("MASK",),
},
}

RETURN_TYPES = (
data_types.MODEL,
data_types.CONDITIONING,
data_types.CONDITIONING,
)
RETURN_NAMES = (
"MODEL",
"positive",
"negative",
)
# FUNCTION = "apply_instantid" use default_function
CATEGORY = "InstantID"
NODE_DISPLAY_NAME = "Apply InstantID"


class ApplyInstantIDAdvanced(ApplyInstantID):
NODE_DISPLAY_NAME = "Apply InstantID Adavanced"

@classmethod
def INPUT_TYPES(s):
return {
"required": {
"instantid": (data_types.INSTANTID,),
"insightface": (data_types.FACEANALYSIS,),
"control_net": (data_types.CONTROL_NET,),
"image": ("IMAGE",),
"model": (data_types.MODEL,),
"positive": (data_types.CONDITIONING,),
"negative": (data_types.CONDITIONING,),
"ip_weight": (
"FLOAT",
{
"default": 0.8,
"min": 0.0,
"max": 3.0,
"step": 0.01,
},
),
"cn_strength": (
"FLOAT",
{
"default": 0.8,
"min": 0.0,
"max": 10.0,
"step": 0.01,
},
),
"start_at": (
"FLOAT",
{
"default": 0.0,
"min": 0.0,
"max": 1.0,
"step": 0.001,
},
),
"end_at": (
"FLOAT",
{
"default": 1.0,
"min": 0.0,
"max": 1.0,
"step": 0.001,
},
),
"noise": (
"FLOAT",
{
"default": 0.0,
"min": 0.0,
"max": 1.0,
"step": 0.1,
},
),
"combine_embeds": (
["average", "norm average", "concat"],
{"default": "average"},
),
},
"optional": {
"image_kps": ("IMAGE",),
"mask": ("MASK",),
},
}


class InstantIDFaceAnalysis(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"provider": (["CUDA"],),
},
}

RETURN_TYPES = (data_types.FACEANALYSIS,)
# FUNCTION = "load_insight_face"
CATEGORY = "InstantID"
NODE_DISPLAY_NAME = "InstantID Face Analysis"
19 changes: 19 additions & 0 deletions bizyair_extras/nodes_controlnet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from comfy.cldm.control_types import UNION_CONTROLNET_TYPES

from bizyair import BizyAirBaseNode, data_types


class SetUnionControlNetType(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"control_net": (data_types.CONTROL_NET,),
"type": (["auto"] + list(UNION_CONTROLNET_TYPES.keys()),),
}
}

CATEGORY = "conditioning/controlnet"
RETURN_TYPES = (data_types.CONTROL_NET,)

# FUNCTION = "set_controlnet_type"
68 changes: 68 additions & 0 deletions bizyair_extras/nodes_image_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import os
import urllib.request

import folder_paths

from bizyair import BizyAirBaseNode
from bizyair.image_utils import encode_data
from nodes import LoadImage


class LoadImageURL(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"url": (
"STRING",
{
"multiline": True, # True if you want the field to look like the one on the ClipTextEncode node
"default": "url or path",
"lazy": True,
},
),
},
}

CATEGORY = "image_utils"
RETURN_TYPES = ("IMAGE", "MASK")
FUNCTION = "apply"
NODE_DISPLAY_NAME = "Load Image (URL)"

def apply(self, url: str):
url = url.strip()
input_dir = folder_paths.get_input_directory()
filename = os.path.basename(url)
file_path = os.path.join(input_dir, filename)

# Check if the file already exists
if os.path.exists(file_path):
print(f"File {filename} already exists, skipping download.")
else:
# Download the image
urllib.request.urlretrieve(url, file_path)
print(f"Image successfully downloaded and saved as {filename}.")
return LoadImage().load_image(filename)


class Image_Encode(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {"image": ("IMAGE",)},
"optional": {
"lossless": (
"BOOLEAN",
{"default": False, "label_on": "yes", "label_off": "no"},
),
},
}

CATEGORY = "image_utils"
FUNCTION = "apply"
RETURN_TYPES = ("IMAGE",)
NODE_DISPLAY_NAME = "Image Encode"

def apply(self, image, lossless=False):
out = encode_data(image, lossless=lossless)
return (out,)
Loading

0 comments on commit b48a222

Please sign in to comment.