Fix mcp input
Browse files- README.md +1 -1
- app.py +14 -5
- modules/constants.py +11 -5
- modules/file_utils.py +35 -0
- modules/storage.md +3 -1
- modules/storage.py +8 -2
README.md
CHANGED
|
@@ -4,7 +4,7 @@ emoji: 🎼
|
|
| 4 |
colorFrom: gray
|
| 5 |
colorTo: red
|
| 6 |
sdk: gradio
|
| 7 |
-
sdk_version: 5.34.
|
| 8 |
python_version: 3.12.8
|
| 9 |
app_file: app.py
|
| 10 |
pinned: true
|
|
|
|
| 4 |
colorFrom: gray
|
| 5 |
colorTo: red
|
| 6 |
sdk: gradio
|
| 7 |
+
sdk_version: 5.34.2
|
| 8 |
python_version: 3.12.8
|
| 9 |
app_file: app.py
|
| 10 |
pinned: true
|
app.py
CHANGED
|
@@ -28,7 +28,7 @@ import librosa
|
|
| 28 |
import modules.user_history
|
| 29 |
from modules.version_info import versions_html, commit_hash, get_xformers_version
|
| 30 |
from modules.gradio import *
|
| 31 |
-
from modules.file_utils import get_file_parts, get_filename_from_filepath, convert_title_to_filename, get_unique_file_path, delete_file
|
| 32 |
|
| 33 |
# Added for MCP call
|
| 34 |
from smolagents.mcp_client import MCPClient
|
|
@@ -383,10 +383,10 @@ def predict(
|
|
| 383 |
"transport": "sse"})
|
| 384 |
tools = mcp_client.get_tools()
|
| 385 |
|
| 386 |
-
predict_tool = next((t for t in tools if t.name
|
| 387 |
|
| 388 |
if not predict_tool:
|
| 389 |
-
raise gr.Error("MCP tool '
|
| 390 |
|
| 391 |
profile_username_to_send = "default_user"
|
| 392 |
if profile_arg:
|
|
@@ -432,15 +432,24 @@ def predict(
|
|
| 432 |
"settings_font_size": settings_font_size_arg,
|
| 433 |
"settings_animate_waveform": settings_animate_waveform_arg,
|
| 434 |
"video_orientation": video_orientation_arg,
|
|
|
|
| 435 |
# "excerpt_duration": excerpt_duration_arg,
|
| 436 |
}
|
| 437 |
|
| 438 |
-
print(f"Calling remote MCP tool '
|
| 439 |
results = predict_tool(**tool_args)
|
| 440 |
print(f"MCP tool call completed. Raw results: {results}")
|
| 441 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 442 |
if not isinstance(results, (list, tuple)) or len(results) != 3:
|
| 443 |
-
raise gr.Error(f"MCP tool '
|
| 444 |
|
| 445 |
waveform_video_path, wave_file_path, seed_used = results
|
| 446 |
|
|
|
|
| 28 |
import modules.user_history
|
| 29 |
from modules.version_info import versions_html, commit_hash, get_xformers_version
|
| 30 |
from modules.gradio import *
|
| 31 |
+
from modules.file_utils import get_file_parts, get_filename_from_filepath, convert_title_to_filename, get_unique_file_path, delete_file, download_and_save_image
|
| 32 |
|
| 33 |
# Added for MCP call
|
| 34 |
from smolagents.mcp_client import MCPClient
|
|
|
|
| 383 |
"transport": "sse"})
|
| 384 |
tools = mcp_client.get_tools()
|
| 385 |
|
| 386 |
+
predict_tool = next((t for t in tools if "predict_simple" in t.name), None)
|
| 387 |
|
| 388 |
if not predict_tool:
|
| 389 |
+
raise gr.Error(f"MCP tool '{predict_tool.name}' not found on the server.")
|
| 390 |
|
| 391 |
profile_username_to_send = "default_user"
|
| 392 |
if profile_arg:
|
|
|
|
| 432 |
"settings_font_size": settings_font_size_arg,
|
| 433 |
"settings_animate_waveform": settings_animate_waveform_arg,
|
| 434 |
"video_orientation": video_orientation_arg,
|
| 435 |
+
"return_history_json": True
|
| 436 |
# "excerpt_duration": excerpt_duration_arg,
|
| 437 |
}
|
| 438 |
|
| 439 |
+
print(f"Calling remote MCP tool '{predict_tool.name}' with arguments (URLs for files).")
|
| 440 |
results = predict_tool(**tool_args)
|
| 441 |
print(f"MCP tool call completed. Raw results: {results}")
|
| 442 |
|
| 443 |
+
if isinstance(results, str) and results.startswith('[') and results.endswith(']'):
|
| 444 |
+
try:
|
| 445 |
+
import ast
|
| 446 |
+
results = ast.literal_eval(results)
|
| 447 |
+
print(f"Parsed results as list: {results}")
|
| 448 |
+
except (SyntaxError, ValueError) as e:
|
| 449 |
+
print(f"Failed to parse results string as list: {e}")
|
| 450 |
+
|
| 451 |
if not isinstance(results, (list, tuple)) or len(results) != 3:
|
| 452 |
+
raise gr.Error(f"MCP tool '{predict_tool.name}' did not return the expected 3 values. Received: {results}")
|
| 453 |
|
| 454 |
waveform_video_path, wave_file_path, seed_used = results
|
| 455 |
|
modules/constants.py
CHANGED
|
@@ -51,14 +51,20 @@ os.makedirs(TMPDIR, exist_ok=True)
|
|
| 51 |
|
| 52 |
|
| 53 |
# Constants for URL shortener
|
| 54 |
-
HF_REPO_ID = "
|
|
|
|
|
|
|
| 55 |
SHORTENER_JSON_FILE = "shortener.json"
|
| 56 |
|
| 57 |
model_extensions = {".glb", ".gltf", ".obj", ".ply"}
|
| 58 |
model_extensions_list = list(model_extensions)
|
| 59 |
image_extensions = {".png", ".jpg", ".jpeg", ".webp"}
|
| 60 |
image_extensions_list = list(image_extensions)
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
|
| 53 |
# Constants for URL shortener
|
| 54 |
+
HF_REPO_ID = os.getenv("HF_REPO_ID")
|
| 55 |
+
if not HF_REPO_ID:
|
| 56 |
+
HF_REPO_ID = "Surn/Storage" # Replace with your Hugging Face repository ID
|
| 57 |
SHORTENER_JSON_FILE = "shortener.json"
|
| 58 |
|
| 59 |
model_extensions = {".glb", ".gltf", ".obj", ".ply"}
|
| 60 |
model_extensions_list = list(model_extensions)
|
| 61 |
image_extensions = {".png", ".jpg", ".jpeg", ".webp"}
|
| 62 |
image_extensions_list = list(image_extensions)
|
| 63 |
+
audio_extensions = {".mp3", ".wav", ".ogg", ".flac"}
|
| 64 |
+
audio_extensions_list = list(audio_extensions)
|
| 65 |
+
video_extensions = {".mp4"}
|
| 66 |
+
video_extensions_list = list(video_extensions)
|
| 67 |
+
upload_file_types = model_extensions_list + image_extensions_list + audio_extensions_list + video_extensions_list
|
| 68 |
+
|
| 69 |
+
umg_mcp_server = "https://surn-unlimitedmusicgen.hf.space/gradio_api/mcp/sse"
|
| 70 |
+
umg_mcp_server0 = "http://127.0.0.1:7860/gradio_api/mcp/sse"
|
modules/file_utils.py
CHANGED
|
@@ -115,3 +115,38 @@ def get_unique_file_path(directory, filename, file_ext, counter=0):
|
|
| 115 |
|
| 116 |
# Example usage:
|
| 117 |
# new_file_path = get_unique_file_path(video_dir, title_file_name, video_new_ext)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
# Example usage:
|
| 117 |
# new_file_path = get_unique_file_path(video_dir, title_file_name, video_new_ext)
|
| 118 |
+
|
| 119 |
+
def download_and_save_image(url: str, dst_folder: Path, token: str = None) -> Path:
|
| 120 |
+
"""
|
| 121 |
+
Downloads an image from a URL with authentication if a token is provided,
|
| 122 |
+
verifies it with PIL, and saves it in dst_folder with a unique filename.
|
| 123 |
+
|
| 124 |
+
Args:
|
| 125 |
+
url (str): The image URL.
|
| 126 |
+
dst_folder (Path): The destination folder for the image.
|
| 127 |
+
token (str, optional): A valid Bearer token. If not provided, the HF_API_TOKEN
|
| 128 |
+
environment variable is used if available.
|
| 129 |
+
|
| 130 |
+
Returns:
|
| 131 |
+
Path: The saved image's file path.
|
| 132 |
+
"""
|
| 133 |
+
headers = {}
|
| 134 |
+
# Use provided token; otherwise, fall back to environment variable.
|
| 135 |
+
api_token = token
|
| 136 |
+
if api_token:
|
| 137 |
+
headers["Authorization"] = f"Bearer {api_token}"
|
| 138 |
+
|
| 139 |
+
response = requests.get(url, headers=headers)
|
| 140 |
+
response.raise_for_status()
|
| 141 |
+
pil_image = Image.open(BytesIO(response.content))
|
| 142 |
+
|
| 143 |
+
parsed_url = urlparse(url)
|
| 144 |
+
original_filename = os.path.basename(parsed_url.path) # e.g., "background.png"
|
| 145 |
+
base, ext = os.path.splitext(original_filename)
|
| 146 |
+
|
| 147 |
+
# Use get_unique_file_path from file_utils.py to generate a unique file path.
|
| 148 |
+
unique_filepath_str = get_unique_file_path(str(dst_folder), base, ext)
|
| 149 |
+
dst = Path(unique_filepath_str)
|
| 150 |
+
dst_folder.mkdir(parents=True, exist_ok=True)
|
| 151 |
+
pil_image.save(dst)
|
| 152 |
+
return dst
|
modules/storage.md
CHANGED
|
@@ -4,6 +4,8 @@ The `storage.py` module provides helper functions for:
|
|
| 4 |
- Generating permalinks for 3D viewer projects.
|
| 5 |
- Uploading files in batches to a Hugging Face repository.
|
| 6 |
- Managing URL shortening by storing (short URL, full URL) pairs in a JSON file on the repository.
|
|
|
|
|
|
|
| 7 |
|
| 8 |
## Key Functions
|
| 9 |
|
|
@@ -53,7 +55,7 @@ files_for_permalink = [
|
|
| 53 |
"local/path/to/heightmap.png",
|
| 54 |
"local/path/to/image.png"
|
| 55 |
]
|
| 56 |
-
repo_id = "Surn/Storage" # Make sure this is defined, e.g., from constants
|
| 57 |
folder_name = "my_new_model_with_permalink"
|
| 58 |
|
| 59 |
upload_result = upload_files_to_repo(
|
|
|
|
| 4 |
- Generating permalinks for 3D viewer projects.
|
| 5 |
- Uploading files in batches to a Hugging Face repository.
|
| 6 |
- Managing URL shortening by storing (short URL, full URL) pairs in a JSON file on the repository.
|
| 7 |
+
- Retrieving full URLs from short URL IDs and vice versa.
|
| 8 |
+
- Handle specific file types for 3D models, images, video and audio.
|
| 9 |
|
| 10 |
## Key Functions
|
| 11 |
|
|
|
|
| 55 |
"local/path/to/heightmap.png",
|
| 56 |
"local/path/to/image.png"
|
| 57 |
]
|
| 58 |
+
repo_id = "Surn/Storage" # Make sure this is defined, e.g., from constants or environment variables
|
| 59 |
folder_name = "my_new_model_with_permalink"
|
| 60 |
|
| 61 |
upload_result = upload_files_to_repo(
|
modules/storage.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
# modules/storage.py
|
| 2 |
-
__version__ = "0.1.
|
| 3 |
import os
|
| 4 |
import urllib.parse
|
| 5 |
import tempfile
|
|
@@ -8,7 +8,7 @@ import json
|
|
| 8 |
import base64
|
| 9 |
from huggingface_hub import login, upload_folder, hf_hub_download, HfApi
|
| 10 |
from huggingface_hub.utils import RepositoryNotFoundError, EntryNotFoundError
|
| 11 |
-
from modules.constants import HF_API_TOKEN, upload_file_types, model_extensions, image_extensions, HF_REPO_ID, SHORTENER_JSON_FILE
|
| 12 |
from typing import Any, Dict, List, Tuple, Union
|
| 13 |
|
| 14 |
# see storage.md for detailed information about the storage module and its functions.
|
|
@@ -21,6 +21,8 @@ def generate_permalink(valid_files, base_url_external, permalink_viewer_url="sur
|
|
| 21 |
"""
|
| 22 |
model_link = None
|
| 23 |
images_links = []
|
|
|
|
|
|
|
| 24 |
for f in valid_files:
|
| 25 |
filename = os.path.basename(f)
|
| 26 |
ext = os.path.splitext(filename)[1].lower()
|
|
@@ -29,6 +31,10 @@ def generate_permalink(valid_files, base_url_external, permalink_viewer_url="sur
|
|
| 29 |
model_link = f"{base_url_external}/{filename}"
|
| 30 |
elif ext in image_extensions:
|
| 31 |
images_links.append(f"{base_url_external}/{filename}")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
if model_link and len(images_links) == 2:
|
| 33 |
# Construct a permalink to the viewer project with query parameters.
|
| 34 |
permalink_viewer_url = f"https://{permalink_viewer_url}/"
|
|
|
|
| 1 |
# modules/storage.py
|
| 2 |
+
__version__ = "0.1.1" # Added version
|
| 3 |
import os
|
| 4 |
import urllib.parse
|
| 5 |
import tempfile
|
|
|
|
| 8 |
import base64
|
| 9 |
from huggingface_hub import login, upload_folder, hf_hub_download, HfApi
|
| 10 |
from huggingface_hub.utils import RepositoryNotFoundError, EntryNotFoundError
|
| 11 |
+
from modules.constants import HF_API_TOKEN, upload_file_types, model_extensions, image_extensions, audio_extensions, video_extensions, HF_REPO_ID, SHORTENER_JSON_FILE
|
| 12 |
from typing import Any, Dict, List, Tuple, Union
|
| 13 |
|
| 14 |
# see storage.md for detailed information about the storage module and its functions.
|
|
|
|
| 21 |
"""
|
| 22 |
model_link = None
|
| 23 |
images_links = []
|
| 24 |
+
audio_links = []
|
| 25 |
+
video_links = []
|
| 26 |
for f in valid_files:
|
| 27 |
filename = os.path.basename(f)
|
| 28 |
ext = os.path.splitext(filename)[1].lower()
|
|
|
|
| 31 |
model_link = f"{base_url_external}/{filename}"
|
| 32 |
elif ext in image_extensions:
|
| 33 |
images_links.append(f"{base_url_external}/{filename}")
|
| 34 |
+
elif ext in audio_extensions:
|
| 35 |
+
audio_links.append(f"{base_url_external}/{filename}")
|
| 36 |
+
elif ext in video_extensions:
|
| 37 |
+
video_links.append(f"{base_url_external}/{filename}")
|
| 38 |
if model_link and len(images_links) == 2:
|
| 39 |
# Construct a permalink to the viewer project with query parameters.
|
| 40 |
permalink_viewer_url = f"https://{permalink_viewer_url}/"
|