diff --git a/.gitignore b/.gitignore index 85cdd2f..c087d5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .aider* +frontend/static/ # Ripped from https://github.com/github/gitignore/blob/main/Python.gitignore # Some things removed because I know they're unused @@ -125,4 +126,4 @@ cython_debug/ .idea/ # PyPI configuration file -.pypirc \ No newline at end of file +.pypirc diff --git a/frontend/build_static.py b/frontend/build_static.py new file mode 100644 index 0000000..9a2de2e --- /dev/null +++ b/frontend/build_static.py @@ -0,0 +1,78 @@ +from jinja2 import Environment, FileSystemLoader +import os +import requests +import argparse + +DEFAULT_TITLE = 'ComfyKiosk - Sample Frontend' +DEFAULT_BACKEND_URL = 'http://localhost:8000' +DEFAULT_OUTPUT_DIR = 'frontend/static' +DEFAULT_FIXED_WORKFLOW_ID = None +DEFAULT_USE_CDN = True +DEFAULT_HIDE_SEED = False + +def build_static_site(api_url=DEFAULT_BACKEND_URL, + fixed_workflow=DEFAULT_FIXED_WORKFLOW_ID, + use_cdn=DEFAULT_USE_CDN, + title=DEFAULT_TITLE, + hide_seed=DEFAULT_HIDE_SEED): + # Ensure api_url is absolute + if not api_url.startswith(('http://', 'https://')): + api_url = 'http://' + api_url + if not use_cdn: + if __name__ != '__main__': + import warnings + warnings.warn(""" + It looks like you're calling build_static_site() as a module while using `use_cdn=False` + This function will only output our html, you must pick up simple.min.css from disk after build_static_site() downloads it. + """, UserWarning) + + # Download simple.min.css from GitHub + css_url = 'https://github.com/kevquirk/simple.css/raw/refs/heads/main/simple.min.css' + css_response = requests.get(css_url) + css_response.raise_for_status() + + # Save simple.css + css_path = os.path.join(output_dir, 'simple.min.css') + with open(css_path, 'wb') as f: + f.write(css_response.content) + + # Set up Jinja environment + env = Environment(loader=FileSystemLoader('frontend/templates')) + + # Render index.html with configuration + template = env.get_template('index.html') + output = template.render( + api_url=api_url, + fixed_workflow=fixed_workflow, + use_cdn=use_cdn, + title=title, + hide_seed=hide_seed + ) + + return output + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Build static frontend for ComfyKiosk') + parser.add_argument('--api-url', help=f'URL of the ComfyKiosk API (default: {DEFAULT_BACKEND_URL})') + parser.add_argument('--title', help=f'Page title (default: {DEFAULT_TITLE})', type=str, nargs='+') + parser.add_argument('--workflow', help=f'Fix to a specific workflow ID (default: {DEFAULT_FIXED_WORKFLOW_ID})') + parser.add_argument('--output-dir', help=f'Output directory (default: {DEFAULT_OUTPUT_DIR})') + parser.add_argument('--download-css', action='store_true', help='Download and serve simple.min.css locally instead of using CDN') + parser.add_argument('--hide-seed', action='store_true', help='Hide the seed input field') + args = parser.parse_args() + + # Create output directory if it doesn't exist + output_dir = args.output_dir or DEFAULT_OUTPUT_DIR + os.makedirs(output_dir, exist_ok=True) + + output = build_static_site( + api_url=args.api_url or DEFAULT_BACKEND_URL, + fixed_workflow=args.workflow, + use_cdn=not args.download_css, + title=' '.join(args.title) if args.title else DEFAULT_TITLE, + hide_seed=args.hide_seed + ) + + # Write to static file + with open(os.path.join(output_dir, 'index.html'), 'w') as f: + f.write(output) diff --git a/frontend/templates/base.html b/frontend/templates/base.html new file mode 100644 index 0000000..56265bd --- /dev/null +++ b/frontend/templates/base.html @@ -0,0 +1,57 @@ + + + + + + {% block title %}Image Generator{% endblock %} + + + {% block head %}{% endblock %} + + + {% block content %}{% endblock %} + + diff --git a/frontend/templates/index.html b/frontend/templates/index.html new file mode 100644 index 0000000..565283a --- /dev/null +++ b/frontend/templates/index.html @@ -0,0 +1,137 @@ +{% extends "base.html" %} + +{% block content %} +

{{ title }}

+ + + +
+
+ {% if not fixed_workflow %} + + {% endif %} + + {% if not hide_seed %} + + {% endif %} + + +
+
+ + +
+
+ +
+
+
+
+
+ + +{% endblock %} diff --git a/requirements.txt b/requirements.txt index a5d03df..80c7163 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,5 @@ uvicorn~=0.32.1 starlette~=0.41.3 pillow~=10.4.0 websockets~=14.1 -more-itertools \ No newline at end of file +more-itertools +jinja2~=3.1.3 \ No newline at end of file diff --git a/sample-advanced.py b/sample-advanced.py index 7e5c749..553046d 100644 --- a/sample-advanced.py +++ b/sample-advanced.py @@ -2,6 +2,7 @@ from comfykiosk import ComfyKiosk, ComfyGenerator, SimpleWorkflowLoader from comfykiosk.image_sources.filesystem import FileSystemImageSource from comfykiosk.image_sources.pregenerate import PreparedGenPool from comfykiosk.fastapi import create_app +from fastapi.middleware.cors import CORSMiddleware # You can compose ComfyKiosk as an alternate way to override defaults filesystem_source = FileSystemImageSource(directory="./output") diff --git a/sample.py b/sample.py index 0af07cc..a8d25a0 100644 --- a/sample.py +++ b/sample.py @@ -1,5 +1,6 @@ from comfykiosk import EasyComfyKiosk from comfykiosk.fastapi import create_app +from fastapi.middleware.cors import CORSMiddleware # Create the image generation service comfy = EasyComfyKiosk()