Spaces:
Sleeping
Sleeping
| 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) | |
| # --------------------------- | |
| 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() |