Spaces:
Running
Running
Add UTM attribution to outbound wavespeed.ai links
Browse files- app.py +2 -1
- spaceui.py +25 -11
- style.css +6 -0
app.py
CHANGED
|
@@ -38,7 +38,8 @@ SPEC = {
|
|
| 38 |
"extra": {
|
| 39 |
"enable_base64_output": False,
|
| 40 |
"enable_sync_mode": False
|
| 41 |
-
}
|
|
|
|
| 42 |
}
|
| 43 |
|
| 44 |
SPEC["css"] = Path(__file__).with_name("style.css").read_text(encoding="utf-8")
|
|
|
|
| 38 |
"extra": {
|
| 39 |
"enable_base64_output": False,
|
| 40 |
"enable_sync_mode": False
|
| 41 |
+
},
|
| 42 |
+
"campaign": "flux2_klein_9b_edit"
|
| 43 |
}
|
| 44 |
|
| 45 |
SPEC["css"] = Path(__file__).with_name("style.css").read_text(encoding="utf-8")
|
spaceui.py
CHANGED
|
@@ -35,11 +35,20 @@ import gradio as gr
|
|
| 35 |
|
| 36 |
import wavespeed as ws
|
| 37 |
|
| 38 |
-
|
| 39 |
|
| 40 |
|
| 41 |
-
def
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
|
| 45 |
def _collect(spec, key, values, progress):
|
|
@@ -85,6 +94,7 @@ def _collect(spec, key, values, progress):
|
|
| 85 |
def build(spec):
|
| 86 |
"""Return a configured gr.Blocks for this Space."""
|
| 87 |
css = spec["css"]
|
|
|
|
| 88 |
outputs_are_video = spec["output"] == "video"
|
| 89 |
|
| 90 |
with gr.Blocks(
|
|
@@ -94,7 +104,8 @@ def build(spec):
|
|
| 94 |
gr.HTML(
|
| 95 |
f"""
|
| 96 |
<div class="hero-container">
|
| 97 |
-
<
|
|
|
|
| 98 |
<h1 class="hero-title">{spec['title']}</h1>
|
| 99 |
<p class="hero-desc">{spec['tagline']}</p>
|
| 100 |
</div>
|
|
@@ -111,8 +122,8 @@ def build(spec):
|
|
| 111 |
scale=4,
|
| 112 |
)
|
| 113 |
gr.HTML(
|
| 114 |
-
f'<a class="get-key-btn" href="{
|
| 115 |
-
'rel="noopener">Get a key</a>'
|
| 116 |
)
|
| 117 |
gr.Markdown(
|
| 118 |
"Your key is sent only to `api.wavespeed.ai` to run this model. "
|
|
@@ -145,11 +156,14 @@ def build(spec):
|
|
| 145 |
gr.HTML(
|
| 146 |
f"""
|
| 147 |
<div class="cta-container">
|
| 148 |
-
<p class="cta-desc">
|
| 149 |
-
<a href="{
|
| 150 |
-
|
| 151 |
-
·
|
| 152 |
-
|
|
|
|
|
|
|
|
|
|
| 153 |
</p>
|
| 154 |
</div>
|
| 155 |
"""
|
|
|
|
| 35 |
|
| 36 |
import wavespeed as ws
|
| 37 |
|
| 38 |
+
SITE = "https://wavespeed.ai"
|
| 39 |
|
| 40 |
|
| 41 |
+
def link(path: str, campaign: str) -> str:
|
| 42 |
+
"""Build an outbound wavespeed.ai URL carrying UTM attribution.
|
| 43 |
+
|
| 44 |
+
Without these, traffic from Hugging Face lands in analytics as plain
|
| 45 |
+
referral with no way to tell which Space produced it.
|
| 46 |
+
"""
|
| 47 |
+
sep = "&" if "?" in path else "?"
|
| 48 |
+
return (
|
| 49 |
+
f"{SITE}{path}{sep}utm_source=huggingface&utm_medium=space"
|
| 50 |
+
f"&utm_campaign={campaign}"
|
| 51 |
+
)
|
| 52 |
|
| 53 |
|
| 54 |
def _collect(spec, key, values, progress):
|
|
|
|
| 94 |
def build(spec):
|
| 95 |
"""Return a configured gr.Blocks for this Space."""
|
| 96 |
css = spec["css"]
|
| 97 |
+
camp = spec["campaign"]
|
| 98 |
outputs_are_video = spec["output"] == "video"
|
| 99 |
|
| 100 |
with gr.Blocks(
|
|
|
|
| 104 |
gr.HTML(
|
| 105 |
f"""
|
| 106 |
<div class="hero-container">
|
| 107 |
+
<a class="hero-badge" href="{link('/', camp)}"
|
| 108 |
+
target="_blank" rel="noopener">WAVESPEED AI</a>
|
| 109 |
<h1 class="hero-title">{spec['title']}</h1>
|
| 110 |
<p class="hero-desc">{spec['tagline']}</p>
|
| 111 |
</div>
|
|
|
|
| 122 |
scale=4,
|
| 123 |
)
|
| 124 |
gr.HTML(
|
| 125 |
+
f'<a class="get-key-btn" href="{link("/dashboard", camp)}" '
|
| 126 |
+
'target="_blank" rel="noopener">Get a key</a>'
|
| 127 |
)
|
| 128 |
gr.Markdown(
|
| 129 |
"Your key is sent only to `api.wavespeed.ai` to run this model. "
|
|
|
|
| 156 |
gr.HTML(
|
| 157 |
f"""
|
| 158 |
<div class="cta-container">
|
| 159 |
+
<p class="cta-desc">Runs
|
| 160 |
+
<a href="{link('/models/' + spec['model'], camp)}"
|
| 161 |
+
target="_blank" rel="noopener"><code>{spec['model']}</code></a>
|
| 162 |
+
on WaveSpeed ·
|
| 163 |
+
<a href="{link('/models', camp)}" target="_blank"
|
| 164 |
+
rel="noopener">Browse all models</a> ·
|
| 165 |
+
<a href="{link('/docs', camp)}" target="_blank"
|
| 166 |
+
rel="noopener">API docs</a>
|
| 167 |
</p>
|
| 168 |
</div>
|
| 169 |
"""
|
style.css
CHANGED
|
@@ -16,6 +16,7 @@
|
|
| 16 |
|
| 17 |
.hero-badge {
|
| 18 |
display: inline-block;
|
|
|
|
| 19 |
background: linear-gradient(135deg, #4f46e5, #2563eb);
|
| 20 |
color: #fff;
|
| 21 |
font-size: 0.66rem;
|
|
@@ -26,6 +27,11 @@
|
|
| 26 |
margin-bottom: 16px;
|
| 27 |
}
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
.hero-title {
|
| 30 |
font-size: 2.4rem;
|
| 31 |
font-weight: 800;
|
|
|
|
| 16 |
|
| 17 |
.hero-badge {
|
| 18 |
display: inline-block;
|
| 19 |
+
text-decoration: none;
|
| 20 |
background: linear-gradient(135deg, #4f46e5, #2563eb);
|
| 21 |
color: #fff;
|
| 22 |
font-size: 0.66rem;
|
|
|
|
| 27 |
margin-bottom: 16px;
|
| 28 |
}
|
| 29 |
|
| 30 |
+
.hero-badge:hover {
|
| 31 |
+
filter: brightness(1.1);
|
| 32 |
+
text-decoration: none;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
.hero-title {
|
| 36 |
font-size: 2.4rem;
|
| 37 |
font-weight: 800;
|