UUID-Generator / app.py
OldKingMeister's picture
fix button
d93cdad
import os
import uuid
import tempfile
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
import gradio as gr
# ---------------------------
# Configuration (no hardcodes)
# ---------------------------
@dataclass
class Config:
# App texts
TITLE: str
INSTRUCTIONS_MD: str
LABEL_COUNT: str
LABEL_OUTPUT: str
LABEL_GENERATE_BTN: str
LABEL_DOWNLOAD_BTN: str
# Behavior and limits
DEFAULT_COUNT: int
MIN_UUIDS: int
MAX_UUIDS: int
# UI layout
TEXTBOX_LINES: int
BUTTON_VARIANT: str # e.g., "primary" | "secondary"
# File output
OUTPUT_DIR: str # if empty, uses temp dir
FILENAME_PREFIX: str
TIME_FORMAT: str # strftime format, e.g. "%Y%m%d_%H%M%S"
FILE_EXTENSION: str # e.g., ".txt"
def getenv_int(key: str, default: int) -> int:
"""Safely parse an int from environment variables with a default."""
try:
return int(os.getenv(key, str(default)))
except Exception:
return default
CFG = Config(
# Texts
TITLE=os.getenv("APP_TITLE", "UUID Generator"),
INSTRUCTIONS_MD=os.getenv(
"APP_INSTRUCTIONS_MD",
"Enter how many UUIDs you want and click **Generate**.",
),
LABEL_COUNT=os.getenv("LABEL_COUNT", "How many UUIDs?"),
LABEL_OUTPUT=os.getenv("LABEL_OUTPUT", "UUIDs (one per line)"),
LABEL_GENERATE_BTN=os.getenv("LABEL_GENERATE_BTN", "Generate"),
LABEL_DOWNLOAD_BTN=os.getenv("LABEL_DOWNLOAD_BTN", "Download as .txt"),
# Behavior and limits
DEFAULT_COUNT=getenv_int("DEFAULT_COUNT", 10),
MIN_UUIDS=getenv_int("MIN_UUIDS", 1),
MAX_UUIDS=getenv_int("MAX_UUIDS", 1000),
# UI layout
TEXTBOX_LINES=getenv_int("TEXTBOX_LINES", 16),
BUTTON_VARIANT=os.getenv("BUTTON_VARIANT", "primary"),
# File output
OUTPUT_DIR=os.getenv("OUTPUT_DIR", ""), # "" -> tempdir
FILENAME_PREFIX=os.getenv("FILENAME_PREFIX", "uuids"),
TIME_FORMAT=os.getenv("TIME_FORMAT", "%Y%m%d_%H%M%S"),
FILE_EXTENSION=os.getenv("FILE_EXTENSION", ".txt"),
)
# ---------------------------
# Core logic
# ---------------------------
def _resolve_output_dir() -> Path:
"""Pick output directory from config or fall back to a temporary directory."""
if CFG.OUTPUT_DIR.strip():
p = Path(CFG.OUTPUT_DIR).expanduser().resolve()
p.mkdir(parents=True, exist_ok=True)
return p
# HF Spaces-friendly temp dir
return Path(tempfile.gettempdir())
def generate_uuids_and_file(count: int):
"""Generate UUIDs (one per line) and create a downloadable file path."""
# Parse and clamp
try:
n = int(count)
except Exception:
n = CFG.DEFAULT_COUNT
n = max(CFG.MIN_UUIDS, min(n, CFG.MAX_UUIDS))
# Build newline-separated UUIDs
text = "\n".join(str(uuid.uuid4()) for _ in range(n))
# Prepare file path
ts = datetime.utcnow().strftime(CFG.TIME_FORMAT)
fname = f"{CFG.FILENAME_PREFIX}_{n}_{ts}{CFG.FILE_EXTENSION}"
outdir = _resolve_output_dir()
fpath = outdir / fname
# Write to file
fpath.write_text(text, encoding="utf-8")
# IMPORTANT: use gr.update(...) instead of DownloadButton.update(...)
return text, gr.update(value=str(fpath), visible=True)
# ---------------------------
# Gradio UI
# ---------------------------
with gr.Blocks(title=CFG.TITLE) as demo:
gr.Markdown(f"# {CFG.TITLE}\n{CFG.INSTRUCTIONS_MD}")
with gr.Row():
num = gr.Number(
value=CFG.DEFAULT_COUNT,
precision=0,
minimum=CFG.MIN_UUIDS,
maximum=CFG.MAX_UUIDS,
label=CFG.LABEL_COUNT,
)
btn = gr.Button(CFG.LABEL_GENERATE_BTN, variant=CFG.BUTTON_VARIANT)
out = gr.Textbox(
label=CFG.LABEL_OUTPUT,
lines=CFG.TEXTBOX_LINES,
show_copy_button=True,
)
# Initially hidden; becomes visible with a valid file path
dbtn = gr.DownloadButton(CFG.LABEL_DOWNLOAD_BTN, visible=False)
btn.click(generate_uuids_and_file, inputs=num, outputs=[out, dbtn])
if __name__ == "__main__":
# Tip: on HF Spaces, set share=True if you want a public link
demo.launch()