Skip to content

Commit a9ecffd

Browse files
committed
Add interactive /playground page with 25 endpoint cards
Browser-based API playground — try every endpoint with zero setup. 4 categories: Domain Intelligence (15), CVE (4), Threat (4), Code Security (2). Pre-filled examples, live Run button with fetch(), JSON syntax highlighting. Nav updated across all pages, CTA links to /playground. CSS v=9, mcp-setup 25 tools count fix.
1 parent f4c33d6 commit a9ecffd

6 files changed

Lines changed: 961 additions & 12 deletions

File tree

app/main.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ def quickstart():
373373
<meta name="viewport" content="width=device-width, initial-scale=1.0">
374374
<title>Quick Start | ContrastAPI</title>
375375
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
376-
<link rel="stylesheet" href="/static/style.css?v=8">
376+
<link rel="stylesheet" href="/static/style.css?v=9">
377377
<style>
378378
.page { max-inline-size: 52rem; margin-inline: auto; padding: 3rem 2rem; position: relative; z-index: 1; }
379379
.page h1 { font-size: 2.25rem; font-weight: 800; letter-spacing: -0.04em; margin-block-end: 0.5rem; }
@@ -403,7 +403,7 @@ def quickstart():
403403
<div class="nav-links">
404404
<a href="/quickstart">API Start</a>
405405
<a href="/mcp-setup">MCP Setup</a>
406-
<a href="https://github.com/UPinar/contrastapi#endpoints">Docs</a>
406+
<a href="/playground">Playground</a>
407407
<a href="https://contrastcyber.com/pricing">Pricing</a>
408408
</div>
409409
</nav>
@@ -510,7 +510,7 @@ def mcp_setup():
510510
<meta name="viewport" content="width=device-width, initial-scale=1.0">
511511
<title>MCP Setup | ContrastAPI</title>
512512
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
513-
<link rel="stylesheet" href="/static/style.css?v=8">
513+
<link rel="stylesheet" href="/static/style.css?v=9">
514514
<style>
515515
.page { max-inline-size: 52rem; margin-inline: auto; padding: 3rem 2rem; position: relative; z-index: 1; }
516516
.page h1 { font-size: 2.25rem; font-weight: 800; letter-spacing: -0.04em; margin-block-end: 0.5rem; }
@@ -546,7 +546,7 @@ def mcp_setup():
546546
<div class="nav-links">
547547
<a href="/quickstart">API Start</a>
548548
<a href="/mcp-setup">MCP Setup</a>
549-
<a href="https://github.com/UPinar/contrastapi#endpoints">Docs</a>
549+
<a href="/playground">Playground</a>
550550
<a href="https://contrastcyber.com/pricing">Pricing</a>
551551
</div>
552552
</nav>
@@ -628,7 +628,7 @@ def mcp_setup():
628628
<p><em>"Is user@example.com a disposable email?"</em></p>
629629
</div>
630630
631-
<h2>24 Tools</h2>
631+
<h2>25 Tools</h2>
632632
<div class="tools-grid">
633633
<div class="tool"><span class="name">domain_report</span> <span class="desc">Full domain security audit</span></div>
634634
<div class="tool"><span class="name">dns_lookup</span> <span class="desc">DNS records</span></div>
@@ -651,6 +651,7 @@ def mcp_setup():
651651
<div class="tool"><span class="name">password_check</span> <span class="desc">Breach database check</span></div>
652652
<div class="tool"><span class="name">phishing_check</span> <span class="desc">URL phishing detection</span></div>
653653
<div class="tool"><span class="name">phone_lookup</span> <span class="desc">Phone number OSINT</span></div>
654+
<div class="tool"><span class="name">username_lookup</span> <span class="desc">Username OSINT across 16 platforms</span></div>
654655
<div class="tool"><span class="name">check_secrets</span> <span class="desc">Hardcoded secret scan</span></div>
655656
<div class="tool"><span class="name">check_injection</span> <span class="desc">SQL/command injection</span></div>
656657
<div class="tool"><span class="name">check_headers</span> <span class="desc">Header validation</span></div>
@@ -683,6 +684,11 @@ def mcp_setup():
683684
)
684685

685686

687+
@app.get("/playground", response_class=HTMLResponse, include_in_schema=False)
688+
def playground(request: Request):
689+
return templates.TemplateResponse(request, "playground.html")
690+
691+
686692
@app.get("/docs", include_in_schema=False)
687693
def custom_docs():
688694
return JSONResponse(

app/static/style.css

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,3 +519,41 @@ footer p { color: var(--text-dim); }
519519
.auth-tiers { grid-template-columns: 1fr; }
520520
footer { padding: 1.5rem 1.25rem; }
521521
}
522+
523+
/* Playground */
524+
.page { max-inline-size: 64rem; margin-inline: auto; padding: 3rem 2rem; position: relative; z-index: 1; }
525+
.page h1 { font-size: 2.25rem; font-weight: 800; letter-spacing: -0.04em; margin-block-end: 0.5rem; }
526+
.page h1 span { background: linear-gradient(135deg, var(--primary), var(--purple)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
527+
.page .subtitle { color: var(--text-dim); margin: 0 0 3rem; max-width: none; }
528+
529+
.pg-card { background: var(--bg-card); border: 1px solid var(--border-dim); border-radius: 0.5rem; padding: 1rem 1.25rem; margin-block-end: 0.75rem; }
530+
.pg-card-header { display: flex; align-items: center; gap: 0.75rem; margin-block-end: 0.75rem; }
531+
.pg-card-header .name { font-size: 0.85rem; font-weight: 600; color: var(--text); }
532+
.pg-card-header .desc { font-size: 0.7rem; color: var(--text-dim); margin-inline-start: auto; }
533+
.pg-inputs { display: flex; align-items: center; gap: 0.5rem; margin-block-end: 0.75rem; flex-wrap: wrap; }
534+
.pg-inputs label { font-size: 0.7rem; color: var(--text-muted); min-width: 3rem; }
535+
.pg-inputs input { flex: 1; min-width: 10rem; background: var(--bg); border: 1px solid var(--border); border-radius: 0.375rem; padding: 0.5rem 0.75rem; color: var(--text); font-family: var(--font-mono); font-size: 0.75rem; outline: none; }
536+
.pg-inputs input:focus { border-color: var(--primary); }
537+
.pg-inputs select { background: var(--bg); border: 1px solid var(--border); border-radius: 0.375rem; padding: 0.5rem 0.75rem; color: var(--text); font-family: var(--font-mono); font-size: 0.75rem; outline: none; }
538+
.pg-inputs select:focus { border-color: var(--primary); }
539+
.btn-run { background: var(--primary); color: #fff; border: none; border-radius: 0.375rem; padding: 0.5rem 1rem; font-family: var(--font-mono); font-size: 0.75rem; font-weight: 600; cursor: pointer; white-space: nowrap; transition: background 0.2s; }
540+
.btn-run:hover { background: var(--primary-hover); }
541+
.btn-run:disabled { opacity: 0.5; cursor: not-allowed; }
542+
.pg-response { background: rgba(9,9,11,0.8); border: 1px solid var(--border-dim); border-radius: 0.375rem; padding: 1rem; max-height: 20rem; overflow: auto; font-size: 0.7rem; line-height: 1.6; }
543+
.pg-response .key { color: #60a5fa; }
544+
.pg-response .str { color: #34d399; }
545+
.pg-response .num { color: #f59e0b; }
546+
.pg-response .bool { color: #c084fc; }
547+
.pg-error { color: var(--red); font-size: 0.75rem; padding: 0.5rem; }
548+
.pg-textarea { width: 100%; background: var(--bg); border: 1px solid var(--border); border-radius: 0.375rem; padding: 0.75rem; color: var(--text); font-family: var(--font-mono); font-size: 0.75rem; resize: vertical; outline: none; }
549+
.pg-textarea:focus { border-color: var(--primary); }
550+
.pg-inputs-col { flex-direction: column; align-items: stretch; }
551+
.pg-inputs-row { display: flex; gap: 0.5rem; align-items: center; margin-block-end: 0.5rem; }
552+
.pg-inputs-row .btn-run { margin-inline-start: auto; }
553+
554+
@media (max-width: 639px) {
555+
.page h1 { font-size: 1.75rem; }
556+
.pg-card-header .desc { display: none; }
557+
.pg-inputs { flex-direction: column; align-items: stretch; }
558+
.pg-inputs input { min-width: 0; }
559+
}

app/templates/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<link rel="alternate" hreflang="en" href="https://api.contrastcyber.com/">
2121
<link rel="alternate" hreflang="zh" href="https://api.contrastcyber.com/cn/">
2222
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
23-
<link rel="stylesheet" href="/static/style.css?v=8">
23+
<link rel="stylesheet" href="/static/style.css?v=9">
2424
<link rel="alternate" type="text/plain" href="/llms.txt" title="LLM Discovery">
2525
<link rel="alternate" type="application/json" href="/openapi.json" title="OpenAPI Spec">
2626
<script type="application/ld+json">
@@ -54,7 +54,7 @@
5454
<div class="nav-links">
5555
<a href="/quickstart">API Start</a>
5656
<a href="/mcp-setup">MCP Setup</a>
57-
<a href="https://github.com/UPinar/contrastapi#endpoints">Docs</a>
57+
<a href="/playground">Playground</a>
5858
<a href="https://contrastcyber.com/pricing">Pricing</a>
5959
</div>
6060
</nav>
@@ -65,7 +65,7 @@ <h1>Security data for<br><span class="gradient">AI models & developers</span></h
6565
<p class="subtitle">35+ endpoints: CVE intelligence, domain reconnaissance, SSL analysis, IP reputation, IOC/malware lookup, exploit search, email security, phone validation, and code security. Structured JSON with LLM-optimized summaries. Free tier included.</p>
6666
<!-- counter removed -->
6767
<div style="text-align:center;margin-top:0.5rem">
68-
<a href="https://contrastcyber.com" class="btn-cta">Try it out →</a>
68+
<a href="/playground" class="btn-cta">Try it out →</a>
6969
</div>
7070
</section>
7171

app/templates/index_cn.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<link rel="alternate" hreflang="en" href="https://api.contrastcyber.com/">
2222
<link rel="alternate" hreflang="zh" href="https://api.contrastcyber.com/cn/">
2323
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
24-
<link rel="stylesheet" href="/static/style.css?v=8">
24+
<link rel="stylesheet" href="/static/style.css?v=9">
2525
<link rel="alternate" type="text/plain" href="/llms.txt" title="LLM Discovery">
2626
<link rel="alternate" type="application/json" href="/openapi.json" title="OpenAPI Spec">
2727
<script type="application/ld+json">
@@ -55,7 +55,7 @@
5555
<div class="nav-links">
5656
<a href="/quickstart">快速入门</a>
5757
<a href="/mcp-setup">MCP 配置</a>
58-
<a href="https://github.com/UPinar/contrastapi">文档</a>
58+
<a href="/playground">Playground</a>
5959
<a href="https://contrastcyber.com/pricing">价格</a>
6060
<a href="/" style="font-size:0.8rem;opacity:0.7">English</a>
6161
</div>
@@ -66,7 +66,7 @@
6666
<h1>为 AI 智能体和开发者<br><span class="gradient">提供安全数据</span></h1>
6767
<p class="subtitle">35+ 个接口:CVE 情报、域名侦察、SSL 分析、IP 信誉、IOC/恶意软件查询、漏洞利用搜索、电子邮件安全、电话号码验证和代码安全扫描。结构化 JSON + LLM 优化摘要。支持 DeepSeek、Qwen、Claude 等 MCP 兼容模型。免费使用。</p>
6868
<div style="text-align:center;margin-top:0.5rem">
69-
<a href="https://contrastcyber.com" class="btn-cta">立即试用 →</a>
69+
<a href="/playground" class="btn-cta">立即试用 →</a>
7070
</div>
7171
</section>
7272

0 commit comments

Comments
 (0)