Fix renderer client kwarg; latest template; editable note; private gallery
Browse files- README.md +1 -1
- __pycache__/certificate_upload_module.cpython-312.pyc +0 -0
- app.py +21 -5
- certificate_upload_module.py +12 -3
README.md
CHANGED
|
@@ -20,6 +20,6 @@ hackathon records β all fields are editable before you generate.
|
|
| 20 |
|
| 21 |
Eligibility is validated against `build-small-hackathon/build-small-apps-for-certificates`
|
| 22 |
(registered participants βͺ Build Small org members βͺ org Space contributors). Generated certificates are saved to the
|
| 23 |
-
|
| 24 |
|
| 25 |
Check the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 20 |
|
| 21 |
Eligibility is validated against `build-small-hackathon/build-small-apps-for-certificates`
|
| 22 |
(registered participants βͺ Build Small org members βͺ org Space contributors). Generated certificates are saved to the
|
| 23 |
+
private dataset `build-small-hackathon/build-small-certificates` (restricted to the org "admins" resource group).
|
| 24 |
|
| 25 |
Check the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
__pycache__/certificate_upload_module.cpython-312.pyc
ADDED
|
Binary file (6.19 kB). View file
|
|
|
app.py
CHANGED
|
@@ -15,6 +15,7 @@ Workflow:
|
|
| 15 |
"""
|
| 16 |
import os
|
| 17 |
import uuid
|
|
|
|
| 18 |
import tempfile
|
| 19 |
import urllib.parse
|
| 20 |
from functools import lru_cache
|
|
@@ -48,10 +49,20 @@ _gradio_client = None
|
|
| 48 |
|
| 49 |
|
| 50 |
def get_gradio_client():
|
| 51 |
-
"""Lazy init of the HTML->image renderer client (avoids event-loop issues).
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
global _gradio_client
|
| 53 |
if _gradio_client is None:
|
| 54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
return _gradio_client
|
| 56 |
|
| 57 |
|
|
@@ -302,13 +313,18 @@ with gr.Blocks(title="Build Small β Certificate Generator") as demo:
|
|
| 302 |
with gr.Column(visible=False) as main_interface:
|
| 303 |
gr.HTML('<div class="bs-section">Your details</div>')
|
| 304 |
data_status = gr.Markdown("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
participant_name = gr.Textbox(
|
| 306 |
-
label="Full name",
|
| 307 |
info="This appears on your certificate β edit if you'd like it shown differently.",
|
| 308 |
)
|
| 309 |
project_name = gr.Textbox(
|
| 310 |
-
label="Project / Space name (optional)",
|
| 311 |
-
info="Auto-filled from your Build Small submission.
|
| 312 |
)
|
| 313 |
with gr.Row(elem_classes=["bs-generate"]):
|
| 314 |
generate_btn = gr.Button("Generate my certificate", variant="primary", size="lg")
|
|
|
|
| 15 |
"""
|
| 16 |
import os
|
| 17 |
import uuid
|
| 18 |
+
import inspect
|
| 19 |
import tempfile
|
| 20 |
import urllib.parse
|
| 21 |
from functools import lru_cache
|
|
|
|
| 49 |
|
| 50 |
|
| 51 |
def get_gradio_client():
|
| 52 |
+
"""Lazy init of the HTML->image renderer client (avoids event-loop issues).
|
| 53 |
+
|
| 54 |
+
The auth kwarg for gradio_client.Client changed across versions
|
| 55 |
+
(`hf_token` vs `token`), so pick whichever the installed version exposes.
|
| 56 |
+
"""
|
| 57 |
global _gradio_client
|
| 58 |
if _gradio_client is None:
|
| 59 |
+
params = inspect.signature(Client.__init__).parameters
|
| 60 |
+
if "hf_token" in params:
|
| 61 |
+
_gradio_client = Client(RENDERER_SPACE, hf_token=HF_TOKEN)
|
| 62 |
+
elif "token" in params:
|
| 63 |
+
_gradio_client = Client(RENDERER_SPACE, token=HF_TOKEN)
|
| 64 |
+
else:
|
| 65 |
+
_gradio_client = Client(RENDERER_SPACE, headers={"Authorization": f"Bearer {HF_TOKEN}"})
|
| 66 |
return _gradio_client
|
| 67 |
|
| 68 |
|
|
|
|
| 313 |
with gr.Column(visible=False) as main_interface:
|
| 314 |
gr.HTML('<div class="bs-section">Your details</div>')
|
| 315 |
data_status = gr.Markdown("")
|
| 316 |
+
gr.Markdown(
|
| 317 |
+
"βοΈ **These details were auto-filled from the Build Small Hackathon records β "
|
| 318 |
+
"you can edit both your name and your project/Space name** below before generating "
|
| 319 |
+
"your certificate."
|
| 320 |
+
)
|
| 321 |
participant_name = gr.Textbox(
|
| 322 |
+
label="Full name (editable)",
|
| 323 |
info="This appears on your certificate β edit if you'd like it shown differently.",
|
| 324 |
)
|
| 325 |
project_name = gr.Textbox(
|
| 326 |
+
label="Project / Space name (editable, optional)",
|
| 327 |
+
info="Auto-filled from your Build Small submission. Edit it, or leave blank for a certificate without a project.",
|
| 328 |
)
|
| 329 |
with gr.Row(elem_classes=["bs-generate"]):
|
| 330 |
generate_btn = gr.Button("Generate my certificate", variant="primary", size="lg")
|
certificate_upload_module.py
CHANGED
|
@@ -11,7 +11,7 @@ from huggingface_hub import HfApi
|
|
| 11 |
logging.basicConfig(level=logging.INFO)
|
| 12 |
logger = logging.getLogger(__name__)
|
| 13 |
|
| 14 |
-
#
|
| 15 |
CERTIFICATE_DATASET_NAME = "build-small-hackathon/build-small-certificates"
|
| 16 |
|
| 17 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
|
@@ -39,7 +39,16 @@ def safe_add_certificate_to_dataset(certificate_image, hf_username, max_retries=
|
|
| 39 |
break
|
| 40 |
except Exception as load_error:
|
| 41 |
error_str = str(load_error).lower()
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
logger.info("Dataset empty / not yet created β will create first entry")
|
| 44 |
is_empty_dataset = True
|
| 45 |
load_successful = True
|
|
@@ -76,7 +85,7 @@ def safe_add_certificate_to_dataset(certificate_image, hf_username, max_retries=
|
|
| 76 |
combined_dataset = new_dataset
|
| 77 |
|
| 78 |
try:
|
| 79 |
-
combined_dataset.push_to_hub(CERTIFICATE_DATASET_NAME, private=
|
| 80 |
logger.info(f"Saved certificate. Total now: {len(combined_dataset)}")
|
| 81 |
return True, f"β
saved to the gallery for {hf_username}."
|
| 82 |
except Exception as upload_error:
|
|
|
|
| 11 |
logging.basicConfig(level=logging.INFO)
|
| 12 |
logger = logging.getLogger(__name__)
|
| 13 |
|
| 14 |
+
# PRIVATE dataset (restricted to the org "admins" resource group) β the archive of issued certificates
|
| 15 |
CERTIFICATE_DATASET_NAME = "build-small-hackathon/build-small-certificates"
|
| 16 |
|
| 17 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
|
|
|
| 39 |
break
|
| 40 |
except Exception as load_error:
|
| 41 |
error_str = str(load_error).lower()
|
| 42 |
+
err_name = type(load_error).__name__.lower()
|
| 43 |
+
empty_signals = (
|
| 44 |
+
"emptydataset" in err_name
|
| 45 |
+
or "corresponds to no data" in error_str
|
| 46 |
+
or "doesn't contain any data" in error_str
|
| 47 |
+
or "no data" in error_str
|
| 48 |
+
or "doesn't exist" in error_str
|
| 49 |
+
or "not found" in error_str
|
| 50 |
+
)
|
| 51 |
+
if empty_signals:
|
| 52 |
logger.info("Dataset empty / not yet created β will create first entry")
|
| 53 |
is_empty_dataset = True
|
| 54 |
load_successful = True
|
|
|
|
| 85 |
combined_dataset = new_dataset
|
| 86 |
|
| 87 |
try:
|
| 88 |
+
combined_dataset.push_to_hub(CERTIFICATE_DATASET_NAME, private=True, token=HF_TOKEN)
|
| 89 |
logger.info(f"Saved certificate. Total now: {len(combined_dataset)}")
|
| 90 |
return True, f"β
saved to the gallery for {hf_username}."
|
| 91 |
except Exception as upload_error:
|