Spaces:
Sleeping
Sleeping
File size: 10,373 Bytes
68991d2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | """
VC Deal Flow Signal — live demo Space.
Three Gradio tabs that exercise the public, no-auth GitDealFlow API:
1. Live signals — top startups by 14-day commit-velocity acceleration.
2. Glossary search — the 84-term controlled vocabulary.
3. Cite this — copy-paste citation snippets for the SSRN paper + dataset.
All data is fetched live from signals.gitdealflow.com/api/v1/* on every
interaction so we never serve stale snapshots. The API is rate-limited,
public, and CC BY 4.0.
License: CC BY 4.0 — attribution required.
Canonical site: https://gitdealflow.com
Methodology paper: https://ssrn.com/abstract=6606558
"""
from __future__ import annotations
import gradio as gr
import requests
BASE = "https://signals.gitdealflow.com"
UA = "vc-deal-flow-signal-hf-space/1.0 (+https://huggingface.co/spaces/the-data-nerd/vc-deal-flow-signal)"
TIMEOUT = 15
def _get_json(path: str) -> dict | list:
"""GET an API endpoint and return parsed JSON, raising on non-2xx."""
url = f"{BASE}{path}"
r = requests.get(url, headers={"User-Agent": UA}, timeout=TIMEOUT)
r.raise_for_status()
return r.json()
# ── Tab 1: Live signals ────────────────────────────────────────────────
def load_signals(limit: int) -> list[list]:
"""Fetch top startups ranked by engineering acceleration."""
try:
data = _get_json("/api/v1/signals.json")
except requests.RequestException as e:
return [["—", "—", "—", "—", f"API unavailable: {e}"]]
# API shape: {"meta": {...}, "trending": [...], "sectors": [...]}.
# Each trending item has: name, description, stage, geography,
# commitVelocity14d, commitVelocityChange, contributors, contributorGrowth,
# newRepos, signalType, githubUrl, websiteUrl.
rows = data.get("trending") if isinstance(data, dict) else []
if not isinstance(rows, list):
return [["—", "—", "—", "—", "Unexpected API shape"]]
out = []
for r in rows[: max(1, min(int(limit), 50))]:
name = r.get("name") or "—"
signal = r.get("signalType") or "—"
delta = r.get("commitVelocityChange") or "—"
stage = r.get("stage") or "—"
# Prefer GitHub deep link (Code-Side Sourcing source of truth).
link = r.get("githubUrl") or r.get("websiteUrl") or BASE
out.append([name, signal, str(delta), stage, link])
if not out:
out = [["—", "—", "—", "—", "No trending signals returned"]]
return out
# ── Tab 2: Glossary search ─────────────────────────────────────────────
def _load_glossary() -> list[dict]:
"""Fetch the controlled vocabulary from the public JSON-LD surface."""
try:
data = _get_json("/api/v1/glossary.json")
except requests.RequestException:
return []
if not isinstance(data, dict):
return []
terms = data.get("hasDefinedTerm") or []
return [t for t in terms if isinstance(t, dict)]
GLOSSARY_CACHE: list[dict] = _load_glossary()
def search_glossary(query: str) -> list[list]:
"""Substring filter across term name + definition."""
q = (query or "").strip().lower()
if not GLOSSARY_CACHE:
return [["—", "Glossary API unavailable — try again in a minute.", "—"]]
if not q:
rows = GLOSSARY_CACHE[:20]
else:
rows = [
t
for t in GLOSSARY_CACHE
if q in (t.get("name") or "").lower()
or q in (t.get("description") or "").lower()
][:50]
if not rows:
return [[f"No match for '{query}'", "—", "—"]]
out = []
for t in rows:
name = t.get("name") or "—"
defn = t.get("description") or "—"
if len(defn) > 280:
defn = defn[:277] + "…"
term_id = t.get("termCode") or ""
link = f"{BASE}/define/{term_id}" if term_id else BASE
out.append([name, defn, link])
return out
# ── Tab 3: Cite this ───────────────────────────────────────────────────
CITATIONS = {
"BibTeX (paper)": """@article{thedatanerd2026vcdealflow,
title = {A Longitudinal Panel of GitHub Engineering Velocity for Venture-Backed Startups},
author = {{The Data Nerd}},
journal = {SSRN Electronic Journal},
year = {2026},
doi = {10.2139/ssrn.6606558},
url = {https://ssrn.com/abstract=6606558},
note = {Published by VC Deal Flow Signal (GitDealFlow). CC BY 4.0.},
orcid = {0009-0002-2222-4112}
}""",
"RIS (paper)": """TY - JOUR
AU - The Data Nerd
TI - A Longitudinal Panel of GitHub Engineering Velocity for Venture-Backed Startups
JO - SSRN Electronic Journal
PY - 2026
DO - 10.2139/ssrn.6606558
UR - https://ssrn.com/abstract=6606558
ER -""",
"APA (paper)": (
"The Data Nerd. (2026). A Longitudinal Panel of GitHub Engineering "
"Velocity for Venture-Backed Startups. SSRN Electronic Journal. "
"https://doi.org/10.2139/ssrn.6606558"
),
"Wikipedia (paper)": (
"<ref>{{cite journal |last=The Data Nerd "
"|title=A Longitudinal Panel of GitHub Engineering Velocity for Venture-Backed Startups "
"|journal=SSRN Electronic Journal |year=2026 |doi=10.2139/ssrn.6606558 "
"|url=https://ssrn.com/abstract=6606558 "
"|publisher=VC Deal Flow Signal (GitDealFlow) "
"|orcid=0009-0002-2222-4112}}</ref>"
),
"Wikipedia (dataset)": (
"<ref>{{cite web |last=The Data Nerd "
"|title=VC Deal Flow Signal — Public Engineering-Velocity Panel "
"|publisher=VC Deal Flow Signal (GitDealFlow) |year=2026 "
"|url=https://signals.gitdealflow.com/api/dataset.jsonl "
"|format=NDJSON |access-date={{subst:CURRENTDATE}}}}</ref>"
),
"HF dataset (BibTeX)": """@dataset{thedatanerd2026vcdealflowglossary,
title = {VC Deal Flow Signal — Controlled Vocabulary Glossary},
author = {{The Data Nerd}},
year = {2026},
publisher = {Hugging Face},
url = {https://huggingface.co/datasets/the-data-nerd/vc-deal-flow-signal-glossary},
license = {CC BY 4.0}
}""",
}
def get_citation(fmt: str) -> str:
return CITATIONS.get(fmt, "")
# ── App layout ─────────────────────────────────────────────────────────
HEADER = """
# 📊 VC Deal Flow Signal
**Engineering acceleration as a leading indicator of fundraise events.**
Three-to-six-week lead time, all from public GitHub data, fully reproducible.
[Methodology paper (SSRN)](https://ssrn.com/abstract=6606558) ·
[Glossary dataset](https://huggingface.co/datasets/the-data-nerd/vc-deal-flow-signal-glossary) ·
[Live API](https://signals.gitdealflow.com/api/v1/openapi.json) ·
[MCP server](https://signals.gitdealflow.com/.well-known/mcp.json) ·
[Wikidata Q139376302](https://www.wikidata.org/wiki/Q139376302)
"""
FOOTER = """
---
Built by [VC Deal Flow Signal](https://gitdealflow.com).
Data is **CC BY 4.0** — free to use commercially, attribution required.
"""
with gr.Blocks(
title="VC Deal Flow Signal — Live Engineering Acceleration",
theme=gr.themes.Soft(primary_hue="blue", neutral_hue="slate"),
) as demo:
gr.Markdown(HEADER)
with gr.Tabs():
with gr.Tab("Live signals"):
gr.Markdown(
"Top startups ranked by 14-day commit-velocity acceleration. "
"Live from `signals.gitdealflow.com/api/v1/signals.json`. "
"Bot filter applied (Dependabot, Renovate, GitHub Actions excluded)."
)
sig_limit = gr.Slider(
minimum=5,
maximum=50,
value=20,
step=5,
label="How many signals to show",
)
sig_btn = gr.Button("Fetch live signals", variant="primary")
sig_table = gr.Dataframe(
headers=[
"Company",
"Signal type",
"Δ velocity (14d)",
"Stage",
"GitHub / website",
],
interactive=False,
wrap=True,
)
sig_btn.click(load_signals, inputs=[sig_limit], outputs=[sig_table])
demo.load(load_signals, inputs=[sig_limit], outputs=[sig_table])
with gr.Tab("Glossary search"):
gr.Markdown(
"Search the 84-term controlled vocabulary. Same corpus as the "
"[`the-data-nerd/vc-deal-flow-signal-glossary`]"
"(https://huggingface.co/datasets/the-data-nerd/vc-deal-flow-signal-glossary) "
"Hugging Face dataset."
)
glossary_query = gr.Textbox(
label="Search term or definition (substring match)",
placeholder="e.g. commit velocity, hiring burst, dream 100…",
)
glossary_table = gr.Dataframe(
headers=["Term", "Definition", "Deep link"],
interactive=False,
wrap=True,
)
glossary_query.change(
search_glossary,
inputs=[glossary_query],
outputs=[glossary_table],
)
demo.load(search_glossary, inputs=[glossary_query], outputs=[glossary_table])
with gr.Tab("Cite this"):
gr.Markdown(
"Copy-paste-ready citation snippets for the SSRN paper, the "
"public dataset, and the Hugging Face glossary corpus."
)
fmt = gr.Radio(
choices=list(CITATIONS.keys()),
value="BibTeX (paper)",
label="Format",
)
cite_box = gr.Code(
language=None,
interactive=False,
lines=10,
)
fmt.change(get_citation, inputs=[fmt], outputs=[cite_box])
demo.load(get_citation, inputs=[fmt], outputs=[cite_box])
gr.Markdown(FOOTER)
if __name__ == "__main__":
demo.queue().launch()
|