pool / app.py
gcharanteja
url fixced
9d7ff8b
Raw
History Blame Contribute Delete
35.2 kB
import os
import tempfile
from typing import Any
import gradio as gr
import httpx
# NOTE: 0.0.0.0 is a bind address, not a connect address.
# Use 127.0.0.1 by default and allow overrides for deployments.
BASE_URL = os.getenv("API_BASE_URL", "http://127.0.0.1:7860")
def _public_base_url(request: gr.Request | None) -> str:
if request is None:
return os.getenv("PUBLIC_BASE_URL", "").rstrip("/")
headers = {k.lower(): v for k, v in dict(request.headers).items()}
origin = headers.get("origin")
if origin:
return origin.rstrip("/")
proto = headers.get("x-forwarded-proto")
host = headers.get("x-forwarded-host") or headers.get("host")
if proto and host:
return f"{proto}://{host}".rstrip("/")
if host:
return f"https://{host}".rstrip("/")
return os.getenv("PUBLIC_BASE_URL", "").rstrip("/")
def create_gradio_app():
"""Create and return the Gradio Blocks app for Music Memories."""
def _maybe_int(value: Any) -> int | None:
if value is None:
return None
try:
return int(value)
except Exception:
return None
def _json_request(
method: str,
path: str,
*,
params: dict[str, Any] | None = None,
data: dict[str, Any] | None = None,
files: dict[str, Any] | None = None,
follow_redirects: bool = True,
timeout: float = 15.0,
) -> dict[str, Any]:
url = f"{BASE_URL}{path}"
with httpx.Client(follow_redirects=follow_redirects, timeout=timeout) as client:
resp = client.request(method, url, params=params, data=data, files=files)
resp.raise_for_status()
return resp.json()
def _redirect_location(path: str, *, params: dict[str, Any] | None = None) -> str:
url = f"{BASE_URL}{path}"
with httpx.Client(follow_redirects=False, timeout=15.0) as client:
resp = client.get(url, params=params)
if resp.status_code in (301, 302, 303, 307, 308):
return resp.headers.get("location") or ""
resp.raise_for_status()
return ""
def add_song_fn(title, artist, album, duration, bpm, energy_level, lyrics, audio_path):
try:
# /songs expects multipart/form-data (Form fields + optional file).
data: dict[str, Any] = {"title": title, "artist": artist}
if album:
data["album"] = album
duration_i = _maybe_int(duration)
if duration_i is not None:
data["duration"] = str(duration_i)
bpm_i = _maybe_int(bpm)
if bpm_i is not None:
data["bpm"] = str(bpm_i)
energy_i = _maybe_int(energy_level)
if energy_i is not None:
data["energy_level"] = str(energy_i)
if lyrics:
data["lyrics"] = lyrics
if audio_path:
filename = os.path.basename(str(audio_path))
with open(str(audio_path), "rb") as f:
files = {"audio_file": (filename, f, "audio/mpeg")}
out = _json_request("POST", "/songs", data=data, files=files)
else:
out = _json_request("POST", "/songs", data=data)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def add_user_fn(name):
try:
out = _json_request("POST", "/users", params={"name": name}, timeout=10.0)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def add_memory_fn(user_id, description, date, song_id):
try:
params: dict[str, Any] = {"user_id": _maybe_int(user_id), "description": description}
if params["user_id"] is None:
raise ValueError("user_id is required")
if date:
params["date"] = date
song_id_i = _maybe_int(song_id)
if song_id_i is not None:
params["song_id"] = song_id_i
out = _json_request("POST", "/memories", params=params)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def add_playlist_fn(name, vibe_code, mood_description):
try:
params: dict[str, Any] = {"name": name}
if vibe_code:
params["vibe_code"] = vibe_code
if mood_description:
params["mood_description"] = mood_description
out = _json_request("POST", "/playlists", params=params)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def add_context_fn(weather, time_of_day, location_type):
try:
params: dict[str, Any] = {}
if weather:
params["weather"] = weather
if time_of_day:
params["time_of_day"] = time_of_day
if location_type:
params["location_type"] = location_type
out = _json_request("POST", "/contexts", params=params, timeout=10.0)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def get_song_fn(song_id):
try:
song_id_i = _maybe_int(song_id)
if song_id_i is None:
raise ValueError("song_id is required")
out = _json_request("GET", f"/songs/{song_id_i}")
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def delete_song_fn(song_id):
try:
song_id_i = _maybe_int(song_id)
if song_id_i is None:
raise ValueError("song_id is required")
out = _json_request("DELETE", f"/songs/{song_id_i}")
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def upload_song_audio_fn(song_id, audio_path):
try:
song_id_i = _maybe_int(song_id)
if song_id_i is None:
raise ValueError("song_id is required")
if not audio_path:
raise ValueError("audio file is required")
filename = os.path.basename(str(audio_path))
with open(str(audio_path), "rb") as f:
files = {"audio_file": (filename, f, "audio/mpeg")}
out = _json_request("POST", f"/songs/{song_id_i}/upload-audio", files=files)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def song_stream_url_fn(song_id, request: gr.Request | None = None):
try:
song_id_i = _maybe_int(song_id)
if song_id_i is None:
raise ValueError("song_id is required")
public_base = _public_base_url(request)
if public_base:
return "Success!", f"{public_base}/songs/{song_id_i}/stream"
return "Success!", f"/songs/{song_id_i}/stream"
except Exception as e:
return "Error", str(e)
def song_download_fn(song_id):
try:
song_id_i = _maybe_int(song_id)
if song_id_i is None:
raise ValueError("song_id is required")
url = f"{BASE_URL}/songs/{song_id_i}/download"
with httpx.Client(timeout=30.0) as client:
resp = client.get(url)
resp.raise_for_status()
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
tmp.write(resp.content)
tmp.flush()
tmp.close()
return "Success!", tmp.name
except Exception as e:
return "Error", None
def get_user_fn(user_id):
try:
user_id_i = _maybe_int(user_id)
if user_id_i is None:
raise ValueError("user_id is required")
out = _json_request("GET", f"/users/{user_id_i}")
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def list_user_memories_fn(user_id):
try:
user_id_i = _maybe_int(user_id)
if user_id_i is None:
raise ValueError("user_id is required")
data = _json_request("GET", f"/users/{user_id_i}/memories", timeout=10.0)
memories = data.get("memories", [])
table = [[m.get("id"), m.get("user_id"), (m.get("description") or "")[:50], m.get("date", "")] for m in memories]
return f"Found {len(memories)} memories", table
except Exception as e:
return "Error", []
def user_activity_fn(user_id, limit, action_type):
try:
user_id_i = _maybe_int(user_id)
if user_id_i is None:
raise ValueError("user_id is required")
params: dict[str, Any] = {}
limit_i = _maybe_int(limit)
if limit_i is not None:
params["limit"] = limit_i
if action_type:
params["action_type"] = action_type
out = _json_request("GET", f"/users/{user_id_i}/activity", params=params)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def delete_playlist_fn(playlist_id):
try:
playlist_id_i = _maybe_int(playlist_id)
if playlist_id_i is None:
raise ValueError("playlist_id is required")
out = _json_request("DELETE", f"/playlists/{playlist_id_i}")
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def list_playlists_fn():
try:
data = _json_request("GET", "/playlists", timeout=10.0)
playlists = data.get("playlists", [])
return [[p.get("id"), p.get("name"), p.get("vibe_code", "")] for p in playlists]
except Exception as e:
return [["Error", str(e), ""]]
def delete_memory_fn(memory_id):
try:
memory_id_i = _maybe_int(memory_id)
if memory_id_i is None:
raise ValueError("memory_id is required")
out = _json_request("DELETE", f"/memories/{memory_id_i}")
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def list_contexts_fn():
try:
data = _json_request("GET", "/contexts", timeout=10.0)
contexts = data.get("contexts", [])
return [[c.get("id"), c.get("weather", ""), c.get("time_of_day", ""), c.get("location_type", "")] for c in contexts]
except Exception as e:
return [["Error", str(e), "", ""]]
def delete_context_fn(context_id):
try:
context_id_i = _maybe_int(context_id)
if context_id_i is None:
raise ValueError("context_id is required")
out = _json_request("DELETE", f"/contexts/{context_id_i}")
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def search_songs_fn(query, n_results):
try:
data = _json_request("GET", "/search/songs", params={"q": query, "n": n_results}, timeout=15.0)
results = data.get("results", [])
table = [[r.get("id"), r.get("title"), r.get("artist"), f"{float(r.get('distance', 0.0)):.4f}"] for r in results] if results else []
return f"Found {len(results)} songs", table
except Exception as e:
return "Error", []
def search_memories_fn(query, n_results):
try:
data = _json_request("GET", "/search/memories", params={"q": query, "n": n_results}, timeout=15.0)
results = data.get("results", [])
table = [[r.get("id"), r.get("user_id"), (r.get("document") or "")[:50], f"{float(r.get('distance', 0.0)):.4f}"] for r in results] if results else []
return f"Found {len(results)} memories", table
except Exception as e:
return "Error", []
def search_contexts_fn(query, n_results):
try:
data = _json_request("GET", "/search/contexts", params={"q": query, "n": n_results}, timeout=15.0)
results = data.get("results", [])
table = [[r.get("id"), r.get("weather"), r.get("time_of_day"), r.get("location_type"), f"{float(r.get('distance', 0.0)):.4f}"] for r in results] if results else []
return f"Found {len(results)} contexts", table
except Exception:
return "Error", []
def search_playlists_fn(query, n_results):
try:
data = _json_request("GET", "/search/playlists", params={"q": query, "n": n_results}, timeout=15.0)
results = data.get("results", [])
table = [[r.get("id"), r.get("name"), f"{float(r.get('distance', 0.0)):.4f}"] for r in results] if results else []
return f"Found {len(results)} playlists", table
except Exception as e:
return "Error", []
def list_songs_fn():
try:
data = _json_request("GET", "/songs", timeout=10.0)
songs = data.get("songs", [])
return [[s.get("id"), s.get("title"), s.get("artist"), s.get("album", ""), s.get("bpm", ""), s.get("has_audio"), s.get("play_count")] for s in songs]
except Exception as e:
return [["Error", str(e), "", "", "", "", ""]]
def list_users_fn():
try:
data = _json_request("GET", "/users", timeout=10.0)
users = data.get("users", [])
return [[u.get("id"), u.get("name"), u.get("created_at", "")] for u in users]
except Exception as e:
return [["Error", str(e), ""]]
def list_memories_fn():
try:
data = _json_request("GET", "/memories", timeout=10.0)
memories = data.get("memories", [])
return [[m.get("id"), m.get("user_id"), (m.get("description") or "")[:50], m.get("date", ""), m.get("song_id", "")] for m in memories]
except Exception as e:
return [["Error", str(e), "", "", ""]]
def list_history_fn(user_id, limit):
try:
params: dict[str, Any] = {}
user_id_i = _maybe_int(user_id)
if user_id_i is not None:
params["user_id"] = user_id_i
limit_i = _maybe_int(limit)
if limit_i is not None:
params["limit"] = limit_i
out = _json_request("GET", "/history", params=params, timeout=20.0)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def add_history_fn(user_id, song_id, context_id, duration_seconds):
try:
params: dict[str, Any] = {}
user_id_i = _maybe_int(user_id)
song_id_i = _maybe_int(song_id)
if user_id_i is None or song_id_i is None:
raise ValueError("user_id and song_id are required")
params["user_id"] = user_id_i
params["song_id"] = song_id_i
context_id_i = _maybe_int(context_id)
if context_id_i is not None:
params["context_id"] = context_id_i
dur_i = _maybe_int(duration_seconds)
if dur_i is not None:
params["duration_seconds"] = dur_i
out = _json_request("POST", "/history", params=params, timeout=20.0)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def analytics_summary_fn(hours):
try:
hours_i = _maybe_int(hours)
params = {"hours": hours_i} if hours_i is not None else {}
out = _json_request("GET", "/analytics/summary", params=params, timeout=20.0)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def analytics_top_songs_fn(limit):
try:
limit_i = _maybe_int(limit)
params = {"limit": limit_i} if limit_i is not None else {}
out = _json_request("GET", "/analytics/top-songs", params=params, timeout=20.0)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def analytics_popular_searches_fn(hours, limit):
try:
params: dict[str, Any] = {}
hours_i = _maybe_int(hours)
limit_i = _maybe_int(limit)
if hours_i is not None:
params["hours"] = hours_i
if limit_i is not None:
params["limit"] = limit_i
out = _json_request("GET", "/analytics/popular-searches", params=params, timeout=20.0)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def storage_files_fn():
try:
out = _json_request("GET", "/storage/files", timeout=20.0)
files = out.get("files", [])
table = [[f.get("object_name"), f.get("size"), f.get("last_modified")] for f in files]
return f"Found {len(files)} files", table
except Exception as e:
return "Error", []
def health_fn():
try:
out = _json_request("GET", "/health", timeout=10.0)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
def root_fn():
try:
out = _json_request("GET", "/", timeout=10.0)
return "Success!", out
except Exception as e:
return "Error", {"error": str(e)}
with gr.Blocks(title="Music Memories UI") as demo:
gr.Markdown("# 🎵 Music Memories")
gr.Markdown("Manage your music library, memories, and playlists with semantic search.")
with gr.Tab("🎶 Songs"):
with gr.Group():
gr.Markdown("### Add Song")
song_title = gr.Textbox(label="Title", placeholder="Song title")
song_artist = gr.Textbox(label="Artist", placeholder="Artist name")
song_album = gr.Textbox(label="Album", placeholder="Album (optional)")
song_duration = gr.Number(label="Duration (seconds)", precision=0)
song_bpm = gr.Number(label="BPM", precision=0)
song_energy = gr.Slider(1, 10, value=5, label="Energy Level")
song_lyrics = gr.Textbox(label="Lyrics", placeholder="Lyrics for semantic search", lines=3)
song_audio = gr.File(label="Audio File (MP3, optional)", file_types=[".mp3"], type="filepath")
song_add_btn = gr.Button("Add Song")
song_add_status = gr.Textbox(label="Status")
song_add_output = gr.JSON(label="Response")
song_add_btn.click(
fn=add_song_fn,
inputs=[song_title, song_artist, song_album, song_duration, song_bpm, song_energy, song_lyrics, song_audio],
outputs=[song_add_status, song_add_output],
)
with gr.Group():
gr.Markdown("### Get / Delete Song")
song_id = gr.Number(label="Song ID", precision=0)
song_get_btn = gr.Button("Get Song")
song_del_btn = gr.Button("Delete Song")
song_action_status = gr.Textbox(label="Status")
song_action_output = gr.JSON(label="Response")
song_get_btn.click(fn=get_song_fn, inputs=[song_id], outputs=[song_action_status, song_action_output])
song_del_btn.click(fn=delete_song_fn, inputs=[song_id], outputs=[song_action_status, song_action_output])
with gr.Group():
gr.Markdown("### Audio: Upload / Stream / Download")
audio_song_id = gr.Number(label="Song ID", precision=0)
audio_upload = gr.File(label="MP3 File", file_types=[".mp3"], type="filepath")
audio_upload_btn = gr.Button("Upload/Update Audio")
audio_upload_status = gr.Textbox(label="Status")
audio_upload_output = gr.JSON(label="Response")
audio_upload_btn.click(
fn=upload_song_audio_fn,
inputs=[audio_song_id, audio_upload],
outputs=[audio_upload_status, audio_upload_output],
)
stream_btn = gr.Button("Get Stream URL")
stream_status = gr.Textbox(label="Status")
stream_url = gr.Textbox(label="Presigned Stream URL")
stream_btn.click(fn=song_stream_url_fn, inputs=[audio_song_id], outputs=[stream_status, stream_url])
download_btn = gr.Button("Download MP3 via API")
download_status = gr.Textbox(label="Status")
download_file = gr.File(label="Downloaded File")
download_btn.click(fn=song_download_fn, inputs=[audio_song_id], outputs=[download_status, download_file])
with gr.Group():
gr.Markdown("### All Songs")
songs_table = gr.Dataframe(headers=["ID", "Title", "Artist", "Album", "BPM", "Has Audio", "Play Count"], label="Songs")
songs_load_btn = gr.Button("Load Songs")
songs_load_btn.click(fn=list_songs_fn, outputs=songs_table)
with gr.Tab("👤 Users"):
with gr.Group():
gr.Markdown("### Add User")
user_name = gr.Textbox(label="Name", placeholder="User name")
user_add_btn = gr.Button("Add User")
user_add_status = gr.Textbox(label="Status")
user_add_output = gr.JSON(label="Response")
user_add_btn.click(fn=add_user_fn, inputs=user_name, outputs=[user_add_status, user_add_output])
with gr.Group():
gr.Markdown("### Get User")
get_user_id = gr.Number(label="User ID", precision=0)
get_user_btn = gr.Button("Get User")
get_user_status = gr.Textbox(label="Status")
get_user_output = gr.JSON(label="Response")
get_user_btn.click(fn=get_user_fn, inputs=[get_user_id], outputs=[get_user_status, get_user_output])
with gr.Group():
gr.Markdown("### User Memories")
um_user_id = gr.Number(label="User ID", precision=0)
um_btn = gr.Button("Load User Memories")
um_summary = gr.Textbox(label="Results")
um_table = gr.Dataframe(headers=["ID", "User ID", "Description", "Date"], label="Memories")
um_btn.click(fn=list_user_memories_fn, inputs=[um_user_id], outputs=[um_summary, um_table])
with gr.Group():
gr.Markdown("### User Activity")
ua_user_id = gr.Number(label="User ID", precision=0)
ua_limit = gr.Number(label="Limit", value=50, precision=0)
ua_action_type = gr.Textbox(label="Action Type (optional)")
ua_btn = gr.Button("Load Activity")
ua_status = gr.Textbox(label="Status")
ua_output = gr.JSON(label="Response")
ua_btn.click(fn=user_activity_fn, inputs=[ua_user_id, ua_limit, ua_action_type], outputs=[ua_status, ua_output])
with gr.Group():
gr.Markdown("### All Users")
users_table = gr.Dataframe(headers=["ID", "Name", "Created At"], label="Users")
users_load_btn = gr.Button("Load Users")
users_load_btn.click(fn=list_users_fn, outputs=users_table)
with gr.Tab("💭 Memories"):
with gr.Group():
gr.Markdown("### Add Memory")
mem_user_id = gr.Number(label="User ID", precision=0)
mem_desc = gr.Textbox(label="Description", placeholder="Describe the memory...", lines=2)
mem_date = gr.Textbox(label="Date (optional)", placeholder="YYYY-MM-DD")
mem_song_id = gr.Number(label="Song ID (optional)", precision=0)
mem_add_btn = gr.Button("Add Memory")
mem_add_status = gr.Textbox(label="Status")
mem_add_output = gr.JSON(label="Response")
mem_add_btn.click(fn=add_memory_fn, inputs=[mem_user_id, mem_desc, mem_date, mem_song_id], outputs=[mem_add_status, mem_add_output])
with gr.Group():
gr.Markdown("### Delete Memory")
del_mem_id = gr.Number(label="Memory ID", precision=0)
del_mem_btn = gr.Button("Delete")
del_mem_status = gr.Textbox(label="Status")
del_mem_output = gr.JSON(label="Response")
del_mem_btn.click(fn=delete_memory_fn, inputs=[del_mem_id], outputs=[del_mem_status, del_mem_output])
with gr.Group():
gr.Markdown("### All Memories")
memories_table = gr.Dataframe(headers=["ID", "User ID", "Description", "Date", "Song ID"], label="Memories")
memories_load_btn = gr.Button("Load Memories")
memories_load_btn.click(fn=list_memories_fn, outputs=memories_table)
with gr.Tab("🎵 Playlists"):
with gr.Group():
gr.Markdown("### Add Playlist")
pl_name = gr.Textbox(label="Name", placeholder="Playlist name")
pl_vibe = gr.Textbox(label="Vibe Code", placeholder="e.g., chill, energetic")
pl_mood = gr.Textbox(label="Mood Description", placeholder="Describe the mood journey...", lines=2)
pl_add_btn = gr.Button("Add Playlist")
pl_add_status = gr.Textbox(label="Status")
pl_add_output = gr.JSON(label="Response")
pl_add_btn.click(fn=add_playlist_fn, inputs=[pl_name, pl_vibe, pl_mood], outputs=[pl_add_status, pl_add_output])
with gr.Group():
gr.Markdown("### All Playlists")
playlists_table = gr.Dataframe(headers=["ID", "Name", "Vibe Code"], label="Playlists")
playlists_load_btn = gr.Button("Load Playlists")
playlists_load_btn.click(fn=list_playlists_fn, outputs=playlists_table)
with gr.Group():
gr.Markdown("### Delete Playlist")
del_pl_id = gr.Number(label="Playlist ID", precision=0)
del_pl_btn = gr.Button("Delete")
del_pl_status = gr.Textbox(label="Status")
del_pl_output = gr.JSON(label="Response")
del_pl_btn.click(fn=delete_playlist_fn, inputs=[del_pl_id], outputs=[del_pl_status, del_pl_output])
with gr.Tab("🌤️ Contexts"):
with gr.Group():
gr.Markdown("### Add Context")
ctx_weather = gr.Textbox(label="Weather", placeholder="e.g., rainy, sunny")
ctx_time = gr.Textbox(label="Time of Day", placeholder="e.g., morning, night")
ctx_location = gr.Textbox(label="Location Type", placeholder="e.g., home, gym, car")
ctx_add_btn = gr.Button("Add Context")
ctx_add_status = gr.Textbox(label="Status")
ctx_add_output = gr.JSON(label="Response")
ctx_add_btn.click(fn=add_context_fn, inputs=[ctx_weather, ctx_time, ctx_location], outputs=[ctx_add_status, ctx_add_output])
with gr.Group():
gr.Markdown("### All Contexts")
ctx_table = gr.Dataframe(headers=["ID", "Weather", "Time of Day", "Location"], label="Contexts")
ctx_load_btn = gr.Button("Load Contexts")
ctx_load_btn.click(fn=list_contexts_fn, outputs=ctx_table)
with gr.Group():
gr.Markdown("### Delete Context")
del_ctx_id = gr.Number(label="Context ID", precision=0)
del_ctx_btn = gr.Button("Delete")
del_ctx_status = gr.Textbox(label="Status")
del_ctx_output = gr.JSON(label="Response")
del_ctx_btn.click(fn=delete_context_fn, inputs=[del_ctx_id], outputs=[del_ctx_status, del_ctx_output])
with gr.Tab("🔍 Semantic Search"):
with gr.Group():
gr.Markdown("### Search Songs by Vibe")
search_songs_query = gr.Textbox(label="Query", placeholder="e.g., 'sad breakup song', 'workout energy'")
search_songs_n = gr.Slider(1, 20, value=5, step=1, label="Results")
search_songs_btn = gr.Button("Search")
search_songs_summary = gr.Textbox(label="Results")
search_songs_table = gr.Dataframe(headers=["ID", "Title", "Artist", "Distance"], label="Songs")
search_songs_btn.click(fn=search_songs_fn, inputs=[search_songs_query, search_songs_n], outputs=[search_songs_summary, search_songs_table])
with gr.Group():
gr.Markdown("### Search Memories")
search_mem_query = gr.Textbox(label="Query", placeholder="e.g., 'summer road trip', 'first dance'")
search_mem_n = gr.Slider(1, 20, value=5, step=1, label="Results")
search_mem_btn = gr.Button("Search")
search_mem_summary = gr.Textbox(label="Results")
search_mem_table = gr.Dataframe(headers=["ID", "User ID", "Description", "Distance"], label="Memories")
search_mem_btn.click(fn=search_memories_fn, inputs=[search_mem_query, search_mem_n], outputs=[search_mem_summary, search_mem_table])
with gr.Group():
gr.Markdown("### Search Contexts")
search_ctx_query = gr.Textbox(label="Query", placeholder="e.g., 'rainy night drive', 'sunny beach'")
search_ctx_n = gr.Slider(1, 20, value=5, step=1, label="Results")
search_ctx_btn = gr.Button("Search")
search_ctx_summary = gr.Textbox(label="Results")
search_ctx_table = gr.Dataframe(headers=["ID", "Weather", "Time", "Location", "Distance"], label="Contexts")
search_ctx_btn.click(fn=search_contexts_fn, inputs=[search_ctx_query, search_ctx_n], outputs=[search_ctx_summary, search_ctx_table])
with gr.Group():
gr.Markdown("### Search Playlists by Mood")
search_pl_query = gr.Textbox(label="Query", placeholder="e.g., 'chill evening vibes', 'party energy'")
search_pl_n = gr.Slider(1, 20, value=5, step=1, label="Results")
search_pl_btn = gr.Button("Search")
search_pl_summary = gr.Textbox(label="Results")
search_pl_table = gr.Dataframe(headers=["ID", "Name", "Distance"], label="Playlists")
search_pl_btn.click(fn=search_playlists_fn, inputs=[search_pl_query, search_pl_n], outputs=[search_pl_summary, search_pl_table])
with gr.Tab("ℹ️ Health"):
with gr.Group():
gr.Markdown("### Root")
root_btn = gr.Button("GET /")
root_status = gr.Textbox(label="Status")
root_output = gr.JSON(label="Response")
root_btn.click(fn=root_fn, outputs=[root_status, root_output])
with gr.Group():
gr.Markdown("### Health")
health_btn = gr.Button("GET /health")
health_status = gr.Textbox(label="Status")
health_output = gr.JSON(label="Response")
health_btn.click(fn=health_fn, outputs=[health_status, health_output])
with gr.Tab("▶️ History"):
with gr.Group():
gr.Markdown("### List History")
hist_user_id = gr.Number(label="User ID (optional)", precision=0)
hist_limit = gr.Number(label="Limit", value=50, precision=0)
hist_list_btn = gr.Button("Load History")
hist_status = gr.Textbox(label="Status")
hist_output = gr.JSON(label="Response")
hist_list_btn.click(fn=list_history_fn, inputs=[hist_user_id, hist_limit], outputs=[hist_status, hist_output])
with gr.Group():
gr.Markdown("### Add Play Event")
hist_add_user = gr.Number(label="User ID", precision=0)
hist_add_song = gr.Number(label="Song ID", precision=0)
hist_add_ctx = gr.Number(label="Context ID (optional)", precision=0)
hist_add_dur = gr.Number(label="Duration Seconds (optional)", precision=0)
hist_add_btn = gr.Button("Add History")
hist_add_status = gr.Textbox(label="Status")
hist_add_output = gr.JSON(label="Response")
hist_add_btn.click(
fn=add_history_fn,
inputs=[hist_add_user, hist_add_song, hist_add_ctx, hist_add_dur],
outputs=[hist_add_status, hist_add_output],
)
with gr.Tab("📊 Analytics"):
with gr.Group():
gr.Markdown("### Summary")
an_hours = gr.Number(label="Hours", value=24, precision=0)
an_sum_btn = gr.Button("Get Summary")
an_sum_status = gr.Textbox(label="Status")
an_sum_output = gr.JSON(label="Response")
an_sum_btn.click(fn=analytics_summary_fn, inputs=[an_hours], outputs=[an_sum_status, an_sum_output])
with gr.Group():
gr.Markdown("### Top Songs")
an_limit = gr.Number(label="Limit", value=10, precision=0)
an_top_btn = gr.Button("Get Top Songs")
an_top_status = gr.Textbox(label="Status")
an_top_output = gr.JSON(label="Response")
an_top_btn.click(fn=analytics_top_songs_fn, inputs=[an_limit], outputs=[an_top_status, an_top_output])
with gr.Group():
gr.Markdown("### Popular Searches")
ps_hours = gr.Number(label="Hours", value=24, precision=0)
ps_limit = gr.Number(label="Limit", value=10, precision=0)
ps_btn = gr.Button("Get Popular Searches")
ps_status = gr.Textbox(label="Status")
ps_output = gr.JSON(label="Response")
ps_btn.click(fn=analytics_popular_searches_fn, inputs=[ps_hours, ps_limit], outputs=[ps_status, ps_output])
with gr.Group():
gr.Markdown("### Storage Files")
sf_btn = gr.Button("List MP3 Files")
sf_summary = gr.Textbox(label="Results")
sf_table = gr.Dataframe(headers=["Object", "Size", "Last Modified"], label="Files")
sf_btn.click(fn=storage_files_fn, outputs=[sf_summary, sf_table])
return demo
# Create the Gradio app instance
gradio_app = create_gradio_app()
if __name__ == "__main__":
gradio_app.launch(share=False, server_name="0.0.0.0", server_port=7860)