Spaces:
Sleeping
Sleeping
Commit
·
a81bd64
1
Parent(s):
16622f2
add download and fix hardcode
Browse files
app.py
CHANGED
|
@@ -1,35 +1,143 @@
|
|
|
|
|
| 1 |
import uuid
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
import gradio as gr
|
| 3 |
|
| 4 |
-
TITLE = "UUID Generator"
|
| 5 |
-
MAX_UUIDS = 1000
|
| 6 |
|
| 7 |
-
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
try:
|
| 10 |
n = int(count)
|
| 11 |
except Exception:
|
| 12 |
-
n =
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
#
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
with gr.Row():
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
-
# Connect button click to function
|
| 32 |
-
btn.click(generate_uuids, inputs=num, outputs=out)
|
| 33 |
|
| 34 |
if __name__ == "__main__":
|
|
|
|
| 35 |
demo.launch()
|
|
|
|
| 1 |
+
import os
|
| 2 |
import uuid
|
| 3 |
+
import tempfile
|
| 4 |
+
from dataclasses import dataclass
|
| 5 |
+
from datetime import datetime
|
| 6 |
+
from pathlib import Path
|
| 7 |
import gradio as gr
|
| 8 |
|
|
|
|
|
|
|
| 9 |
|
| 10 |
+
# ---------------------------
|
| 11 |
+
# Configuration (no hardcodes)
|
| 12 |
+
# ---------------------------
|
| 13 |
+
@dataclass
|
| 14 |
+
class Config:
|
| 15 |
+
# App texts
|
| 16 |
+
TITLE: str
|
| 17 |
+
INSTRUCTIONS_MD: str
|
| 18 |
+
LABEL_COUNT: str
|
| 19 |
+
LABEL_OUTPUT: str
|
| 20 |
+
LABEL_GENERATE_BTN: str
|
| 21 |
+
LABEL_DOWNLOAD_BTN: str
|
| 22 |
+
|
| 23 |
+
# Behavior and limits
|
| 24 |
+
DEFAULT_COUNT: int
|
| 25 |
+
MIN_UUIDS: int
|
| 26 |
+
MAX_UUIDS: int
|
| 27 |
+
|
| 28 |
+
# UI layout
|
| 29 |
+
TEXTBOX_LINES: int
|
| 30 |
+
BUTTON_VARIANT: str # e.g., "primary" | "secondary"
|
| 31 |
+
|
| 32 |
+
# File output
|
| 33 |
+
OUTPUT_DIR: str # if empty, uses temp dir
|
| 34 |
+
FILENAME_PREFIX: str
|
| 35 |
+
TIME_FORMAT: str # strftime format, e.g. "%Y%m%d_%H%M%S"
|
| 36 |
+
FILE_EXTENSION: str # e.g., ".txt"
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def getenv_int(key: str, default: int) -> int:
|
| 40 |
+
"""Safely parse an int from environment variables with a default."""
|
| 41 |
+
try:
|
| 42 |
+
return int(os.getenv(key, str(default)))
|
| 43 |
+
except Exception:
|
| 44 |
+
return default
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
CFG = Config(
|
| 48 |
+
# Texts
|
| 49 |
+
TITLE=os.getenv("APP_TITLE", "UUID Generator"),
|
| 50 |
+
INSTRUCTIONS_MD=os.getenv(
|
| 51 |
+
"APP_INSTRUCTIONS_MD",
|
| 52 |
+
"Enter how many UUIDs you want and click **Generate**.",
|
| 53 |
+
),
|
| 54 |
+
LABEL_COUNT=os.getenv("LABEL_COUNT", "How many UUIDs?"),
|
| 55 |
+
LABEL_OUTPUT=os.getenv("LABEL_OUTPUT", "UUIDs (one per line)"),
|
| 56 |
+
LABEL_GENERATE_BTN=os.getenv("LABEL_GENERATE_BTN", "Generate"),
|
| 57 |
+
LABEL_DOWNLOAD_BTN=os.getenv("LABEL_DOWNLOAD_BTN", "Download as .txt"),
|
| 58 |
+
|
| 59 |
+
# Behavior and limits
|
| 60 |
+
DEFAULT_COUNT=getenv_int("DEFAULT_COUNT", 10),
|
| 61 |
+
MIN_UUIDS=getenv_int("MIN_UUIDS", 1),
|
| 62 |
+
MAX_UUIDS=getenv_int("MAX_UUIDS", 1000),
|
| 63 |
+
|
| 64 |
+
# UI layout
|
| 65 |
+
TEXTBOX_LINES=getenv_int("TEXTBOX_LINES", 16),
|
| 66 |
+
BUTTON_VARIANT=os.getenv("BUTTON_VARIANT", "primary"),
|
| 67 |
+
|
| 68 |
+
# File output
|
| 69 |
+
OUTPUT_DIR=os.getenv("OUTPUT_DIR", ""), # "" -> tempdir
|
| 70 |
+
FILENAME_PREFIX=os.getenv("FILENAME_PREFIX", "uuids"),
|
| 71 |
+
TIME_FORMAT=os.getenv("TIME_FORMAT", "%Y%m%d_%H%M%S"),
|
| 72 |
+
FILE_EXTENSION=os.getenv("FILE_EXTENSION", ".txt"),
|
| 73 |
+
)
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
# ---------------------------
|
| 77 |
+
# Core logic
|
| 78 |
+
# ---------------------------
|
| 79 |
+
def _resolve_output_dir() -> Path:
|
| 80 |
+
"""Pick output directory from config or fall back to a temporary directory."""
|
| 81 |
+
if CFG.OUTPUT_DIR.strip():
|
| 82 |
+
p = Path(CFG.OUTPUT_DIR).expanduser().resolve()
|
| 83 |
+
p.mkdir(parents=True, exist_ok=True)
|
| 84 |
+
return p
|
| 85 |
+
# HF Spaces-friendly temp dir
|
| 86 |
+
return Path(tempfile.gettempdir())
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
def generate_uuids_and_file(count: int):
|
| 90 |
+
"""Generate UUIDs (one per line) and create a downloadable file path."""
|
| 91 |
+
# Parse and clamp
|
| 92 |
try:
|
| 93 |
n = int(count)
|
| 94 |
except Exception:
|
| 95 |
+
n = CFG.DEFAULT_COUNT
|
| 96 |
+
n = max(CFG.MIN_UUIDS, min(n, CFG.MAX_UUIDS))
|
| 97 |
+
|
| 98 |
+
# Build newline-separated UUIDs
|
| 99 |
+
text = "\n".join(str(uuid.uuid4()) for _ in range(n))
|
| 100 |
+
|
| 101 |
+
# Prepare file path
|
| 102 |
+
ts = datetime.utcnow().strftime(CFG.TIME_FORMAT)
|
| 103 |
+
fname = f"{CFG.FILENAME_PREFIX}_{n}_{ts}{CFG.FILE_EXTENSION}"
|
| 104 |
+
outdir = _resolve_output_dir()
|
| 105 |
+
fpath = outdir / fname
|
| 106 |
+
|
| 107 |
+
# Write to file
|
| 108 |
+
fpath.write_text(text, encoding="utf-8")
|
| 109 |
+
|
| 110 |
+
# Return both the text and a download button linked to the file
|
| 111 |
+
return text, gr.DownloadButton.update(value=str(fpath), visible=True)
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
# ---------------------------
|
| 115 |
+
# Gradio UI
|
| 116 |
+
# ---------------------------
|
| 117 |
+
with gr.Blocks(title=CFG.TITLE) as demo:
|
| 118 |
+
gr.Markdown(f"# {CFG.TITLE}\n{CFG.INSTRUCTIONS_MD}")
|
| 119 |
+
|
| 120 |
with gr.Row():
|
| 121 |
+
num = gr.Number(
|
| 122 |
+
value=CFG.DEFAULT_COUNT,
|
| 123 |
+
precision=0,
|
| 124 |
+
minimum=CFG.MIN_UUIDS,
|
| 125 |
+
maximum=CFG.MAX_UUIDS,
|
| 126 |
+
label=CFG.LABEL_COUNT,
|
| 127 |
+
)
|
| 128 |
+
btn = gr.Button(CFG.LABEL_GENERATE_BTN, variant=CFG.BUTTON_VARIANT)
|
| 129 |
+
|
| 130 |
+
out = gr.Textbox(
|
| 131 |
+
label=CFG.LABEL_OUTPUT,
|
| 132 |
+
lines=CFG.TEXTBOX_LINES,
|
| 133 |
+
show_copy_button=True,
|
| 134 |
+
)
|
| 135 |
+
|
| 136 |
+
dbtn = gr.DownloadButton(CFG.LABEL_DOWNLOAD_BTN, visible=False)
|
| 137 |
+
|
| 138 |
+
btn.click(generate_uuids_and_file, inputs=num, outputs=[out, dbtn])
|
| 139 |
|
|
|
|
|
|
|
| 140 |
|
| 141 |
if __name__ == "__main__":
|
| 142 |
+
# On HF Spaces, `demo.launch()` can be plain; config via env vars controls behavior/labels.
|
| 143 |
demo.launch()
|