Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Batch File upload/ Folder upload. Bulk Enhance #3540

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f1e9a5c
Batch File upload/ Folder upload. Bulk Enhance
ChrisColeTech Aug 18, 2024
ee4f442
remove unused imports
ChrisColeTech Aug 18, 2024
9f535e8
Change to resolve GitHub Advanced Security check
ChrisColeTech Aug 18, 2024
7a0b8ee
Rework Stop/Skip while bulk enhancing
ChrisColeTech Aug 18, 2024
2ab91c9
Update bulk_enhance_helpers.py
ChrisColeTech Aug 19, 2024
ec177f2
Update bulk_enhance_helpers.py
ChrisColeTech Aug 19, 2024
ad18a93
Update async_worker.py
ChrisColeTech Aug 20, 2024
e268cd5
Merge branch 'lllyasviel:main' into dev
ChrisColeTech Aug 20, 2024
83d0935
more code cleanup
ChrisColeTech Aug 20, 2024
3db125a
To resolve github CodeQL warning
ChrisColeTech Aug 20, 2024
4b90d70
Update async_worker.py
ChrisColeTech Aug 21, 2024
67edbf2
Update bulk_enhance_helpers.py
ChrisColeTech Aug 21, 2024
e68d7b5
automatic tkinter installation
ChrisColeTech Aug 22, 2024
1afc7b3
Update tkinter_installer.py
ChrisColeTech Aug 22, 2024
672baf0
Update launch.py
ChrisColeTech Aug 23, 2024
8921ac8
Remove code comments, added backend logic for perf monitor. renamed t…
ChrisColeTech Aug 24, 2024
7722d2c
html front end component for resource monitor
ChrisColeTech Aug 24, 2024
4848427
wired up perf monitor
ChrisColeTech Aug 24, 2024
85429b0
Update launch.py
ChrisColeTech Aug 24, 2024
4c32ebe
final touches on the perf monitor
ChrisColeTech Aug 26, 2024
5774787
perf monitor 2.0 with dragging
ChrisColeTech Aug 29, 2024
f0fa022
fix invisible element
ChrisColeTech Aug 30, 2024
c5a290a
remove unused code
ChrisColeTech Aug 30, 2024
c8d4d2d
Merge branch 'dev' of https://github.com/ChrisColeTech/Fooocus into dev
ChrisColeTech Aug 30, 2024
ce74b6b
speed up animation
ChrisColeTech Aug 30, 2024
eb934c9
Using websockets for resource monitor instead of rest api
ChrisColeTech Sep 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ user_path_config-deprecated.txt
/.coverage*
/auth.json
.DS_Store
/.venv
23 changes: 23 additions & 0 deletions api/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import os
import importlib
from flask import Blueprint
from flask_restx import Namespace


def register_blueprints(app, api):
"""Register all Blueprints to the Flask app automatically."""
controllers_dir = os.path.dirname(__file__)
for filename in os.listdir(controllers_dir):
if filename.endswith('_controller.py') and filename != '__init__.py':
module_name = filename[:-3] # Remove ".py"
module = importlib.import_module(
f'.{module_name}', package=__package__)
for attribute_name in dir(module):
attribute = getattr(module, attribute_name)
if isinstance(attribute, Namespace):
api.add_namespace(attribute)

if isinstance(attribute, Blueprint):
app.register_blueprint(
attribute)
print(f"Registered blueprint: {attribute_name}")
105 changes: 105 additions & 0 deletions api/controllers/gpu_usage_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
from flask_restx import Api, Resource, fields, Namespace
from flask import jsonify, request, make_response, Blueprint
import psutil
import GPUtil
import time

# Create a Blueprint for the gpu_usage controller
gpu_usage_bp = Blueprint('gpu_usage', __name__)
gpu_usage_api = Api(gpu_usage_bp, version='1.0', title='gpu_usage API',
description='API for managing gpu_usage')

# Define a namespace for gpu_usage
gpu_usage_ns = Namespace('gpu_usage', description='gpu usage operations')

# Define the model for a gpu
gpu_model = gpu_usage_ns.model('gpu_usage', {
'id': fields.Integer(required=True, description='The unique identifier of the gpu'),
'description': fields.String(required=True, description='Description of the gpu'),
'status': fields.String(description='Status of the gpu')
})

# Cache for system usage data
cache = {
'timestamp': 0,
'data': {
'cpu': 0,
'ram': 0,
'gpu': 0,
'vram': 0,
'hdd': 0,
'temp': 0
}
}
CACHE_DURATION = 1 # Cache duration in seconds


@gpu_usage_ns.route('/')
class GPUInfo(Resource):
def get_cache(self, current_time):
# Get CPU utilization
cpu_percent = psutil.cpu_percent(interval=0)

# Get Memory utilization
mem = psutil.virtual_memory()
mem_percent = mem.percent

# Get GPU utilization (considering only the first GPU)
gpus = GPUtil.getGPUs()
gpu_percent = gpus[0].load * 100 if gpus else 0

# Get VRAM usage (considering only the first GPU)
vram_usage = 0
if gpus:
used = gpus[0].memoryUsed
total = gpus[0].memoryTotal
vram_usage = (used / total) * 100

# Get HDD usage (assuming usage of the primary disk)
hdd = psutil.disk_usage('/')
hdd_percent = hdd.percent

# Get temperature (if available)
temperature = gpus[0].temperature

# Update the cache
cache['data'] = {
'cpu': cpu_percent,
'ram': mem_percent,
'gpu': gpu_percent,
'vram': vram_usage, # Convert bytes to MB
'hdd': hdd_percent,
'temp': temperature # Add temperature
}
cache['timestamp'] = current_time
return cache

def get(self):
if request.method == "OPTIONS": # CORS preflight
return _build_cors_preflight_response()

current_time = time.time()

# Check if the cache is still valid
if current_time - cache['timestamp'] < CACHE_DURATION:
return _corsify_actual_response(jsonify(cache['data']))

try:
self.get_cache(current_time)

return _corsify_actual_response(jsonify(cache['data']))
except Exception as e:
return _corsify_actual_response(jsonify({'error': str(e)}))

Check warning

Code scanning / CodeQL

Information exposure through an exception

[Stack trace information](1) flows to this location and may be exposed to an external user.


def _build_cors_preflight_response():
response = make_response()
response.headers.add("Access-Control-Allow-Origin", "*")
response.headers.add("Access-Control-Allow-Headers", "*")
response.headers.add("Access-Control-Allow-Methods", "*")
return response


def _corsify_actual_response(response):
response.headers.add("Access-Control-Allow-Origin", "*")
return response
59 changes: 59 additions & 0 deletions api/http_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from flask import Flask, send_from_directory, jsonify, render_template
from flask_restx import Api
import threading
import logging
from flask_cors import CORS
import args_manager
from .controllers import register_blueprints
import os
import gradio as gr
import shared

def load_page(filename):
"""Load an HTML file as a string and return it"""
file_path = os.path.join("web", filename)
with open(file_path, 'r') as file:
content = file.read()
return content

def addResourceMonitor():
ceq = None
with gr.Row():
ceq = gr.HTML(load_page('templates/perf-monitor/index.html'))

return ceq

# Suppress the Flask development server warning
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR) # Set level to ERROR to suppress warnings

title = f"Elegant Resource Monitor"
app = Flask(title, static_folder='web/assets', template_folder='web/templates')
app.config['CORS_HEADERS'] = 'Content-Type'
api = Api(app, version='1.0', title=title, description='Elegant Resource Monitor REST API')

# Register blueprints (API endpoints)
register_blueprints(app, api)

# Enable CORS for all origins
CORS(app, resources={r"/*": {"origins": "*"}})

gradio_app = shared.gradio_root

@app.route('/<path:filename>')
def serve_static(filename):
return send_from_directory('web', filename)

@app.route('/config')
def config():
return jsonify({
'base_url': f"http://{str(args_manager.args.listen)}:5000"
})

def run_app():
app.run(port=5000)


# Start Flask app in a separate thread
thread = threading.Thread(target=run_app)
thread.start()
Loading