Really-amin's picture
Upload static/pages/help/index.html with huggingface_hub
6da966e verified
Raw
History Blame Contribute Delete
21.6 kB
<!DOCTYPE html>
<html lang="en" dir="ltr" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Complete API Help Guide for Crypto Monitor on Hugging Face Spaces">
<title>Help & API Guide | Crypto Monitor</title>
<link rel="icon" type="image/svg+xml" href="/static/assets/icons/favicon.svg">
<link rel="stylesheet" href="/static/shared/css/design-system.css">
<link rel="stylesheet" href="/static/shared/css/global.css">
<link rel="stylesheet" href="/static/shared/css/components.css">
<link rel="stylesheet" href="/static/shared/css/layout.css">
<link rel="stylesheet" href="/static/pages/help/help.css?v=5.0">
<script src="/static/js/api-config.js"></script>
</head>
<body>
<div class="app-container">
<aside id="sidebar-container"></aside>
<main class="main-content">
<header id="header-container"></header>
<div class="page-content">
<div class="page-header">
<div class="page-title">
<h1>Help & API Guide</h1>
<p class="page-subtitle">
Complete English reference for <strong>Datasourceforcryptocurrency-2</strong> (primary Space) and
<strong>v4 complement</strong>. Copy any example and run it β€” no setup beyond this URL.
</p>
<p class="page-subtitle">
<strong>API Base:</strong> <code id="api-base-display"></code>
&nbsp;|&nbsp; <a href="/docs" target="_blank">Swagger UI</a>
&nbsp;|&nbsp; <a href="/api-explorer">API Explorer</a>
&nbsp;|&nbsp; <a href="/help/legacy">Extended legacy guide</a>
&nbsp;|&nbsp; <a href="/api/pages/catalog">Pages catalog API</a>
</p>
</div>
</div>
<div class="help-search-wrap">
<input type="search" id="help-search" placeholder="Search help (e.g. sentiment, models, rotation)..." aria-label="Search help">
</div>
<div id="live-stats" class="live-stats" aria-live="polite">Loading live system stats...</div>
<div class="help-layout">
<nav class="help-toc" aria-label="Table of contents">
<h3>Contents</h3>
<ul>
<li><a href="#quick-start">Quick Start</a></li>
<li><a href="#discovery">Discovery</a></li>
<li><a href="#dashboard">Dashboard API</a></li>
<li><a href="#market">Market Data</a></li>
<li><a href="#sentiment">Sentiment</a></li>
<li><a href="#models">AI Models</a></li>
<li><a href="#rotation">Rotation & Keys</a></li>
<li><a href="#news">News</a></li>
<li><a href="#indicators">Indicators</a></li>
<li><a href="#v4">v4 Complement</a></li>
<li><a href="#errors">Errors</a></li>
</ul>
</nav>
<div class="help-main">
<section class="help-section" id="quick-start">
<h2>1. Quick Start (3 steps)</h2>
<p>Every example uses your current origin. Replace <code>BASE</code> if you call from another app.</p>
<div class="code-wrap">
<button class="copy-btn" type="button" data-copy="">Copy</button>
<pre class="code-block"><code>const BASE = window.location.origin; // e.g. https://really-amin-datasourceforcryptocurrency-2.hf.space
// Step 1 β€” Is the server alive?
const health = await fetch(`${BASE}/health`).then(r => r.json());
console.log(health.status); // "healthy"
// Step 2 β€” Dashboard numbers (cards on home page)
const dash = await fetch(`${BASE}/api/dashboard/overview`).then(r => r.json());
console.log(dash.cards);
// Step 3 β€” Analyze one sentence
const sentiment = await fetch(`${BASE}/api/sentiment`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: 'Bitcoin looks bullish today' })
}).then(r => r.json());
console.log(sentiment.sentiment, sentiment.confidence);</code></pre>
</div>
<p class="help-note"><strong>Python:</strong> use <code>requests.get(BASE + "/health")</code> the same way. Always set <code>timeout=30</code> on HF Spaces.</p>
</section>
<section class="help-section" id="discovery">
<h2>2. Discovery & Health</h2>
<p>Find every endpoint before you integrate.</p>
<table class="api-table">
<thead><tr><th>Method</th><th>Path</th><th>What you get</th></tr></thead>
<tbody>
<tr><td class="method-get">GET</td><td><code>/health</code></td><td>Simple alive check (also <code>/api/health</code>)</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/status</code></td><td>Provider connectivity probe</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/system/status</code></td><td>Full system drawer data (pools, models, keys)</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/endpoints</code></td><td>Grouped list of all routes</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/routers</code></td><td>Which routers are loaded</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/uptime/probe</code></td><td>Probe 12 critical endpoints</td></tr>
<tr><td class="method-get">GET</td><td><code>/docs</code></td><td>Interactive Swagger UI</td></tr>
</tbody>
</table>
<div class="code-wrap">
<button class="copy-btn" type="button">Copy</button>
<pre class="code-block"><code>curl "%BASE%/api/endpoints"
curl "%BASE%/api/routers"</code></pre>
</div>
</section>
<section class="help-section" id="dashboard">
<h2>3. Dashboard API</h2>
<p>The home dashboard reads one endpoint for all hero cards.</p>
<table class="api-table">
<thead><tr><th>Method</th><th>Path</th><th>Response highlights</th></tr></thead>
<tbody>
<tr><td class="method-get">GET</td><td><code>/api/dashboard/overview</code></td><td><code>cards</code>: resources, API keys, models v2+v4, rotation pools</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/resources/summary</code></td><td>Registry totals and categories</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/models/summary</code></td><td>Models by category + v4 complement block</td></tr>
</tbody>
</table>
<div class="code-wrap">
<button class="copy-btn" type="button">Copy</button>
<pre class="code-block"><code>const overview = await fetch(`${BASE}/api/dashboard/overview`).then(r => r.json());
// cards.total_resources, cards.api_keys_env, cards.api_keys_file
// cards.models_loaded_v2, cards.models_loaded_v4, cards.pools_healthy</code></pre>
</div>
</section>
<section class="help-section" id="market">
<h2>4. Market Data</h2>
<p>Prices, top coins, OHLCV. Automatic fallback: local β†’ Binance β†’ v4 complement β†’ cache.</p>
<table class="api-table">
<thead><tr><th>Method</th><th>Path</th><th>Parameters</th></tr></thead>
<tbody>
<tr><td class="method-get">GET</td><td><code>/api/market?limit=50</code></td><td>Top market rows for dashboard table</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/coins/top?limit=50</code></td><td>Top coins by market cap</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/trending</code></td><td>Trending coins</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/ohlcv?symbol=BTC&amp;timeframe=1h&amp;limit=100</code></td><td>Candles for charts</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/klines?symbol=BTCUSDT&amp;interval=1h&amp;limit=100</code></td><td>Binance-style alias</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/market/gainers?limit=20</code></td><td>Top gainers (with fallbacks)</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/market/losers?limit=20</code></td><td>Top losers</td></tr>
</tbody>
</table>
<div class="code-wrap">
<button class="copy-btn" type="button">Copy</button>
<pre class="code-block"><code>// Market table data
const market = await fetch(`${BASE}/api/market?limit=20`).then(r => r.json());
// OHLCV for TradingView-style charts
const ohlcv = await fetch(`${BASE}/api/ohlcv?symbol=BTC&timeframe=1h&limit=200`).then(r => r.json());</code></pre>
</div>
</section>
<section class="help-section" id="sentiment">
<h2>5. Sentiment & Fear/Greed</h2>
<table class="api-table">
<thead><tr><th>Method</th><th>Path</th><th>Body / notes</th></tr></thead>
<tbody>
<tr><td class="method-get">GET</td><td><code>/api/fear-greed?limit=30</code></td><td>Fear &amp; Greed index + history</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/sentiment/global</code></td><td>Global market mood</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/sentiment/asset/BTC</code></td><td>Per-asset sentiment</td></tr>
<tr><td class="method-post">POST</td><td><code>/api/sentiment</code></td><td><code>{"text":"..."}</code> β€” v2 then v4 fallback</td></tr>
<tr><td class="method-post">POST</td><td><code>/api/sentiment/analyze</code></td><td><code>{"text":"...","mode":"crypto"}</code></td></tr>
<tr><td class="method-post">POST</td><td><code>/api/hf/run-sentiment</code></td><td><code>{"texts":["sentence 1"]}</code> β€” must be array</td></tr>
</tbody>
</table>
<div class="code-wrap">
<button class="copy-btn" type="button">Copy</button>
<pre class="code-block"><code>// Fear & Greed (dashboard chart)
const fng = await fetch(`${BASE}/api/fear-greed?limit=30`).then(r => r.json());
// Text sentiment
const result = await fetch(`${BASE}/api/sentiment`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: 'ETH breaking resistance, very bullish' })
}).then(r => r.json());</code></pre>
</div>
</section>
<section class="help-section" id="models">
<h2>6. AI Models (Hugging Face)</h2>
<p><strong>v2</strong> loads models locally when possible. <strong>v4 complement</strong> adds more models via Inference API when v2 is exhausted.</p>
<table class="api-table">
<thead><tr><th>Method</th><th>Path</th><th>Purpose</th></tr></thead>
<tbody>
<tr><td class="method-get">GET</td><td><code>/api/models/summary</code></td><td>Best for UI β€” categories + v4 block</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/models/status</code></td><td>Registry status, <code>models_loaded</code></td></tr>
<tr><td class="method-get">GET</td><td><code>/api/models/list</code></td><td>Full catalog</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/models/health</code></td><td>Per-model health entries</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/hf/models</code></td><td>Alias β†’ models list</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/hf/health</code></td><td>HF connectivity check</td></tr>
<tr><td class="method-post">POST</td><td><code>/api/models/reinitialize</code></td><td>Warm models again</td></tr>
<tr><td class="method-post">POST</td><td><code>/api/ai/decision</code></td><td><code>{"symbol":"BTC","horizon":"swing"}</code></td></tr>
</tbody>
</table>
<div class="code-wrap">
<button class="copy-btn" type="button">Copy</button>
<pre class="code-block"><code>const summary = await fetch(`${BASE}/api/models/summary`).then(r => r.json());
console.log('v2 loaded:', summary.summary?.loaded_models);
console.log('v4 loaded:', summary.complement_v4?.loaded);
// HF sentiment batch (texts must be an array)
await fetch(`${BASE}/api/hf/run-sentiment`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ texts: ['BTC pump incoming'] })
});</code></pre>
</div>
<p class="help-note">Set Space secret <code>HF_TOKEN</code> and variable <code>HF_MODE=auth</code> for gated models. v4 Space uses Inference API when local torch is unavailable.</p>
</section>
<section class="help-section" id="rotation">
<h2>7. API Keys, Resources & Rotation</h2>
<p>Keys come from <strong>HF Secrets</strong> (env) plus <strong>inline keys</strong> in <code>config/api_keys.json</code>. Rotation uses <code>api-resources/crypto_resources_unified_2025-11-11.json</code> (10 pools).</p>
<h3>Recommended Space secrets</h3>
<ul class="help-list">
<li><code>CRYPTOCOMPARE_API_KEY</code>, <code>COINMARKETCAP_KEY_1</code>, <code>COINMARKETCAP_KEY_2</code></li>
<li><code>ETHERSCAN_KEY_1</code>, <code>ETHERSCAN_KEY_2</code>, <code>BSCSCAN_API_KEY</code>, <code>TRONSCAN_API_KEY</code></li>
<li><code>NEWSAPI_KEY</code>, <code>HF_TOKEN</code>, <code>COINGECKO_API_KEY</code> (optional)</li>
</ul>
<table class="api-table">
<thead><tr><th>Method</th><th>Path</th><th>Purpose</th></tr></thead>
<tbody>
<tr><td class="method-get">GET</td><td><code>/api/resources/rotation/health</code></td><td>10 pools + env key probe</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/resources/rotation</code></td><td>Full rotation status</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/resources/fallback-chains</code></td><td>Failover chain JSON</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/resources/summary</code></td><td>Registry + key counts</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/providers</code></td><td>Named provider list</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/complement/v4/status</code></td><td>v4 Space health</td></tr>
</tbody>
</table>
<div class="code-wrap">
<button class="copy-btn" type="button">Copy</button>
<pre class="code-block"><code>const rotation = await fetch(`${BASE}/api/resources/rotation/health`).then(r => r.json());
console.log(rotation.pools_healthy, '/', rotation.pools_total);
console.log('Env keys:', rotation.env_keys?.configured);</code></pre>
</div>
</section>
<section class="help-section" id="news">
<h2>8. News</h2>
<table class="api-table">
<thead><tr><th>Method</th><th>Path</th><th>Notes</th></tr></thead>
<tbody>
<tr><td class="method-get">GET</td><td><code>/api/news/latest?limit=20</code></td><td>Latest crypto news</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/news?limit=20</code></td><td>Alias</td></tr>
</tbody>
</table>
<div class="code-wrap">
<button class="copy-btn" type="button">Copy</button>
<pre class="code-block"><code>const news = await fetch(`${BASE}/api/news/latest?limit=10`).then(r => r.json());
(news.articles || news.news || []).forEach(a => console.log(a.title));</code></pre>
</div>
</section>
<section class="help-section" id="indicators">
<h2>9. Indicators & Technical Analysis</h2>
<table class="api-table">
<thead><tr><th>Method</th><th>Path</th><th>Notes</th></tr></thead>
<tbody>
<tr><td class="method-get">GET</td><td><code>/api/indicators/services</code></td><td>List indicator services</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/indicators/rsi?symbol=BTC&amp;timeframe=1h</code></td><td>RSI</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/indicators/macd?symbol=BTC&amp;timeframe=1h</code></td><td>MACD</td></tr>
<tr><td class="method-get">GET</td><td><code>/api/indicators/comprehensive?symbol=BTC</code></td><td>Multi-indicator bundle</td></tr>
<tr><td class="method-post">POST</td><td><code>/api/technical/ta-quick</code></td><td>Body: symbol, timeframe, ohlcv array</td></tr>
<tr><td class="method-post">POST</td><td><code>/api/technical/comprehensive</code></td><td>Combined TA + FA + on-chain</td></tr>
</tbody>
</table>
<div class="code-wrap">
<button class="copy-btn" type="button">Copy</button>
<pre class="code-block"><code>const ohlcv = await fetch(`${BASE}/api/ohlcv?symbol=BTC&timeframe=4h&limit=200`).then(r => r.json());
const ta = await fetch(`${BASE}/api/technical/ta-quick`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ symbol: 'BTC', timeframe: '4h', ohlcv: ohlcv.data })
}).then(r => r.json());</code></pre>
</div>
</section>
<section class="help-section" id="v4">
<h2>10. v4 Complement Space</h2>
<p>Secondary Space: <code>https://really-amin-datasourceforcryptocurrency-4.hf.space</code>. v2 calls it when local providers or models are exhausted.</p>
<ul class="help-list">
<li>v2 <code>POST /api/sentiment</code> β†’ local model β†’ v4 β†’ lexical fallback</li>
<li>v2 <code>/api/models/summary</code> includes <code>complement_v4</code> counts</li>
<li>v4 runs HF Inference API with <code>HF_MODE=auth</code> when torch is unavailable</li>
</ul>
<div class="code-wrap">
<button class="copy-btn" type="button">Copy</button>
<pre class="code-block"><code>const v4 = await fetch(`${BASE}/api/complement/v4/status`).then(r => r.json());
console.log(v4.probe); // endpoints_ok, healthy</code></pre>
</div>
</section>
<section class="help-section" id="errors">
<h2>11. Errors & Tips</h2>
<ol class="help-steps">
<li><strong>404 on route</strong> β€” Check <code>/api/endpoints</code> or <code>/docs</code>; path may differ from old docs.</li>
<li><strong>503 on market</strong> β€” CoinGecko rate limit; retry or use <code>/api/market</code> (Binance fallback).</li>
<li><strong>422 on sentiment</strong> β€” <code>/api/hf/run-sentiment</code> requires <code>{"texts":["..."]}</code> (array), not a single string.</li>
<li><strong>Empty models</strong> β€” Call <code>POST /api/models/reinitialize</code> or wait for lazy load; check <code>HF_TOKEN</code>.</li>
<li><strong>Space sleeping</strong> β€” First request may take 30–60s; increase client timeout.</li>
<li><strong>Hard refresh UI</strong> β€” <code>Ctrl+Shift+R</code> after deploys.</li>
</ol>
<h3>Diagnostic checklist</h3>
<div class="code-wrap">
<button class="copy-btn" type="button">Copy</button>
<pre class="code-block"><code>curl "%BASE%/health"
curl "%BASE%/api/dashboard/overview"
curl "%BASE%/api/resources/rotation/health"
curl "%BASE%/api/models/summary"</code></pre>
</div>
<p class="help-note">
<strong>HTTP only required.</strong> WebSocket endpoints are optional; the dashboard polls REST every 30 seconds.
For interactive testing, open <a href="/docs">/docs</a> or click the green <strong>?</strong> floating button on the dashboard.
</p>
</section>
</div>
</div>
</div>
</main>
</div>
<script type="module">
import { LayoutManager } from '/static/shared/js/core/layout-manager.js';
import HelpPage from '/static/pages/help/help.js?v=5.0';
document.getElementById('api-base-display').textContent = window.location.origin;
document.querySelectorAll('.code-wrap').forEach(wrap => {
const code = wrap.querySelector('code');
const btn = wrap.querySelector('.copy-btn');
if (code && btn) {
btn.setAttribute('data-copy', code.textContent.replace(/%BASE%/g, window.location.origin));
code.textContent = code.textContent.replace(/%BASE%/g, window.location.origin);
}
});
document.addEventListener('DOMContentLoaded', async () => {
await LayoutManager.init('help');
const page = new HelpPage();
await page.init();
});
</script>
</body>
</html>