fishapi / templates /dashboard.html
kamau1's picture
update
4e4f208 verified
Raw
History Blame Contribute Delete
27.6 kB
{% extends "base.html" %}
{% block title %}Dashboard - Seamo Species API{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="/static/css/dashboard.css">
<link rel="stylesheet" href="/static/css/dashboard-simple.css">
{% endblock %}
{% block content %}
<div class="dashboard">
<!-- API Status Banner -->
<div class="status-banner" id="statusBanner">
<div class="status-indicator">
<span class="status-dot" id="statusDot"></span>
<span class="status-text" id="statusText">Checking API status...</span>
</div>
<div class="model-info" id="modelInfo"></div>
</div>
<!-- Main Dashboard Grid -->
<div class="dashboard-grid">
<!-- Model Information Panel -->
<div class="panel model-panel">
<div class="card">
<div class="card-header">
<h3 class="card-title">Model Information</h3>
</div>
<div class="card-body">
<!-- Detection Settings -->
<div class="settings-section">
<h4>Detection Settings</h4>
<div class="settings-grid">
<div class="setting-item">
<label for="confidenceSlider">Confidence Threshold</label>
<div class="slider-container">
<input type="range" id="confidenceSlider" min="0" max="100" value="25">
<span class="slider-value" id="confidenceValue">25%</span>
</div>
</div>
<div class="setting-item">
<label for="iouSlider">IoU Threshold</label>
<div class="slider-container">
<input type="range" id="iouSlider" min="0" max="100" value="45">
<span class="slider-value" id="iouValue">45%</span>
</div>
</div>
</div>
</div>
<!-- Model Details -->
<div class="model-details-section">
<h4>Model Details</h4>
<div class="model-details-grid">
<div class="detail-item">
<span class="detail-label">Model Type</span>
<span class="detail-value" id="modelType">YOLOv5</span>
</div>
<div class="detail-item">
<span class="detail-label">Total Species</span>
<span class="detail-value" id="totalSpecies">-</span>
</div>
<div class="detail-item">
<span class="detail-label">Device</span>
<span class="detail-value" id="deviceInfo">-</span>
</div>
<div class="detail-item">
<span class="detail-label">Model Size</span>
<span class="detail-value" id="modelSize">33k Images</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Upload & Test Panel -->
<div class="panel upload-panel">
<div class="card">
<div class="card-header">
<h3 class="card-title">Upload & Test</h3>
</div>
<div class="card-body">
<!-- Upload Area -->
<div class="upload-area" id="uploadArea">
<div class="upload-content">
<div class="upload-icon">+</div>
<div class="upload-text">
<p class="upload-primary">Drag image here or click to browse</p>
<p class="upload-secondary">PNG, JPG, JPEG up to 10MB</p>
</div>
</div>
<input type="file" id="fileInput" accept="image/*" hidden>
</div>
<!-- Action Button -->
<button class="btn btn-primary btn-full" id="identifyBtn" disabled>
Identify Species
</button>
<!-- Sample Images -->
<div class="sample-images-section">
<div class="sample-images-header">
<h4>Try Sample Images</h4>
<div class="slider-controls">
<button class="slider-btn slider-btn-prev" id="sliderPrev" aria-label="Previous images"></button>
<button class="slider-btn slider-btn-next" id="sliderNext" aria-label="Next images"></button>
</div>
</div>
<div class="sample-images-slider" id="sampleImagesSlider">
<!-- Sample images will be populated here -->
</div>
</div>
</div>
</div>
</div>
<!-- Results Panel -->
<div class="panel results-panel">
<div class="card">
<div class="card-header">
<h3 class="card-title">Detection Results</h3>
</div>
<div class="card-body">
<!-- Annotated Image -->
<div class="annotated-section">
<h4>Annotated Image</h4>
<div class="image-container" id="annotatedImageContainer">
<div class="image-placeholder">
<div class="placeholder-icon"></div>
<p>Annotated results will appear here</p>
</div>
</div>
</div>
<!-- Detection Metadata -->
<div class="metadata-section" id="metadataSection" style="display: none;">
<h4>Detection Summary</h4>
<div class="metadata-grid">
<div class="metadata-item">
<span class="metadata-label">Processing Time</span>
<span class="metadata-value" id="processingTime">-</span>
</div>
<div class="metadata-item">
<span class="metadata-label">Species Found</span>
<span class="metadata-value" id="speciesCount">-</span>
</div>
<div class="metadata-item">
<span class="metadata-label">Image Size</span>
<span class="metadata-value" id="imageSize">-</span>
</div>
</div>
</div>
<!-- Species List -->
<div class="species-section" id="speciesSection" style="display: none;">
<h4>Detected Species</h4>
<div class="species-list" id="speciesList">
<!-- Species items will be populated here -->
</div>
</div>
</div>
</div>
</div>
</div>
<!-- API Documentation Section -->
<div class="api-documentation-section">
<div class="api-docs-header">
<h2>API Documentation</h2>
</div>
<div class="api-overview">
<div class="endpoint-card">
<div class="endpoint-header">
<span class="method-badge">POST</span>
<code class="endpoint-url">https://seamo-ai-fishapi.hf.space/api/v1/detect</code>
<span class="status-badge">Live</span>
</div>
<div class="features-grid">
<div class="feature-item">
<div class="feature-title">691 Species</div>
<div class="feature-description">Comprehensive marine life detection</div>
</div>
<div class="feature-item">
<div class="feature-title">~2 seconds</div>
<div class="feature-description">Fast AI-powered processing</div>
</div>
<div class="feature-item">
<div class="feature-title">Precise Locations</div>
<div class="feature-description">Bounding boxes with confidence scores</div>
</div>
<div class="feature-item">
<div class="feature-title">Annotated Images</div>
<div class="feature-description">Visual results with species labels</div>
</div>
</div>
</div>
</div>
<!-- Tabs Navigation -->
<div class="tabs-container">
<div class="tabs-nav">
<button class="tab-button active" data-tab="curl">cURL</button>
<button class="tab-button" data-tab="python">Python</button>
<button class="tab-button" data-tab="javascript">JavaScript</button>
<button class="tab-button" data-tab="csharp">C#</button>
<button class="tab-button" data-tab="response">Response</button>
</div>
<!-- cURL Tab -->
<div class="tab-content active" id="curl-tab">
<div class="code-section">
<div class="code-header">
<span class="code-title">cURL Request</span>
<button class="copy-button" onclick="copyCode('curl-code')">Copy</button>
</div>
<pre class="code-block" id="curl-code"><span class="comment"># Easy one-liner with automatic base64 conversion</span>
<span class="cmd">curl</span> <span class="flag">-X</span> <span class="method">POST</span> <span class="string">"https://seamo-ai-fishapi.hf.space/api/v1/detect"</span> <span class="operator">\</span>
<span class="flag">-H</span> <span class="string">"Content-Type: application/json"</span> <span class="operator">\</span>
<span class="flag">-d</span> <span class="string">"{
\"image\": \"$(base64 -i your_image.jpg | tr -d '\n')\",
\"confidence_threshold\": 0.25,
\"iou_threshold\": 0.45,
\"return_annotated_image\": true
}"</span></pre>
</div>
</div>
<!-- Python Tab -->
<div class="tab-content" id="python-tab">
<div class="code-section">
<div class="code-header">
<span class="code-title">Python Request</span>
<button class="copy-button" onclick="copyCode('python-code')">Copy</button>
</div>
<pre class="code-block" id="python-code"><span class="keyword">import</span> <span class="module">requests</span>
<span class="keyword">import</span> <span class="module">base64</span>
<span class="variable">url</span> <span class="operator">=</span> <span class="string">"https://seamo-ai-fishapi.hf.space/api/v1/detect"</span>
<span class="comment"># Read and encode image</span>
<span class="keyword">with</span> <span class="function">open</span>(<span class="string">"your_image.jpg"</span>, <span class="string">"rb"</span>) <span class="keyword">as</span> <span class="variable">f</span>:
<span class="variable">image_data</span> <span class="operator">=</span> <span class="variable">base64</span>.<span class="function">b64encode</span>(<span class="variable">f</span>.<span class="function">read</span>()).<span class="function">decode</span>()
<span class="variable">payload</span> <span class="operator">=</span> {
<span class="string">"image"</span>: <span class="variable">image_data</span>,
<span class="string">"confidence_threshold"</span>: <span class="number">0.25</span>,
<span class="string">"iou_threshold"</span>: <span class="number">0.45</span>,
<span class="string">"return_annotated_image"</span>: <span class="keyword">True</span>
}
<span class="variable">response</span> <span class="operator">=</span> <span class="variable">requests</span>.<span class="function">post</span>(<span class="variable">url</span>, <span class="variable">json</span>=<span class="variable">payload</span>)
<span class="variable">result</span> <span class="operator">=</span> <span class="variable">response</span>.<span class="function">json</span>()
<span class="function">print</span>(<span class="string">f"Found </span>{<span class="function">len</span>(<span class="variable">result</span>[<span class="string">'detections'</span>])}<span class="string"> species"</span>)
<span class="keyword">for</span> <span class="variable">detection</span> <span class="keyword">in</span> <span class="variable">result</span>[<span class="string">'detections'</span>]:
<span class="function">print</span>(<span class="string">f"- </span>{<span class="variable">detection</span>[<span class="string">'class_name'</span>]}<span class="string">: </span>{<span class="variable">detection</span>[<span class="string">'confidence'</span>]:<span class="string">.2%</span>}<span class="string">"</span>)</pre>
</div>
</div>
<!-- JavaScript Tab -->
<div class="tab-content" id="javascript-tab">
<div class="code-section">
<div class="code-header">
<span class="code-title">JavaScript Request</span>
<button class="copy-button" onclick="copyCode('js-code')">Copy</button>
</div>
<pre class="code-block" id="js-code"><span class="comment">// Convert file to base64</span>
<span class="keyword">function</span> <span class="function">fileToBase64</span>(<span class="variable">file</span>) {
<span class="keyword">return</span> <span class="keyword">new</span> <span class="function">Promise</span>((<span class="variable">resolve</span>, <span class="variable">reject</span>) <span class="operator">=></span> {
<span class="keyword">const</span> <span class="variable">reader</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="function">FileReader</span>();
<span class="variable">reader</span>.<span class="property">onload</span> <span class="operator">=</span> () <span class="operator">=></span> <span class="function">resolve</span>(<span class="variable">reader</span>.<span class="property">result</span>.<span class="function">split</span>(<span class="string">','</span>)[<span class="number">1</span>]);
<span class="variable">reader</span>.<span class="property">onerror</span> <span class="operator">=</span> <span class="variable">reject</span>;
<span class="variable">reader</span>.<span class="function">readAsDataURL</span>(<span class="variable">file</span>);
});
}
<span class="keyword">const</span> <span class="variable">imageBase64</span> <span class="operator">=</span> <span class="keyword">await</span> <span class="function">fileToBase64</span>(<span class="variable">fileInput</span>.<span class="property">files</span>[<span class="number">0</span>]);
<span class="keyword">const</span> <span class="variable">payload</span> <span class="operator">=</span> {
<span class="property">image</span>: <span class="variable">imageBase64</span>,
<span class="property">confidence_threshold</span>: <span class="number">0.25</span>,
<span class="property">iou_threshold</span>: <span class="number">0.45</span>,
<span class="property">return_annotated_image</span>: <span class="keyword">true</span>
};
<span class="function">fetch</span>(<span class="string">'https://seamo-ai-fishapi.hf.space/api/v1/detect'</span>, {
<span class="property">method</span>: <span class="string">'POST'</span>,
<span class="property">headers</span>: { <span class="string">'Content-Type'</span>: <span class="string">'application/json'</span> },
<span class="property">body</span>: <span class="function">JSON</span>.<span class="function">stringify</span>(<span class="variable">payload</span>)
})
.<span class="function">then</span>(<span class="variable">response</span> <span class="operator">=></span> <span class="variable">response</span>.<span class="function">json</span>())
.<span class="function">then</span>(<span class="variable">data</span> <span class="operator">=></span> {
<span class="variable">console</span>.<span class="function">log</span>(<span class="string">`Found </span>${<span class="variable">data</span>.<span class="property">detections</span>.<span class="property">length</span>}<span class="string"> species`</span>);
<span class="variable">data</span>.<span class="property">detections</span>.<span class="function">forEach</span>(<span class="variable">detection</span> <span class="operator">=></span> {
<span class="variable">console</span>.<span class="function">log</span>(<span class="string">`</span>${<span class="variable">detection</span>.<span class="property">class_name</span>}<span class="string">: </span>${(<span class="variable">detection</span>.<span class="property">confidence</span> <span class="operator">*</span> <span class="number">100</span>).<span class="function">toFixed</span>(<span class="number">1</span>)}<span class="string">%`</span>);
});
})
.<span class="function">catch</span>(<span class="variable">error</span> <span class="operator">=></span> <span class="variable">console</span>.<span class="function">error</span>(<span class="string">'Error:'</span>, <span class="variable">error</span>));</pre>
</div>
</div>
<!-- C# Tab -->
<div class="tab-content" id="csharp-tab">
<div class="code-section">
<div class="code-header">
<span class="code-title">C# Request</span>
<button class="copy-button" onclick="copyCode('csharp-code')">Copy</button>
</div>
<pre class="code-block" id="csharp-code"><span class="keyword">using</span> <span class="namespace">System</span>;
<span class="keyword">using</span> <span class="namespace">System.IO</span>;
<span class="keyword">using</span> <span class="namespace">System.Net.Http</span>;
<span class="keyword">using</span> <span class="namespace">System.Text</span>;
<span class="keyword">using</span> <span class="namespace">System.Threading.Tasks</span>;
<span class="keyword">using</span> <span class="namespace">Newtonsoft.Json</span>;
<span class="keyword">var</span> <span class="variable">client</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="function">HttpClient</span>();
<span class="comment">// Read and encode image</span>
<span class="keyword">var</span> <span class="variable">imageBytes</span> <span class="operator">=</span> <span class="class">File</span>.<span class="function">ReadAllBytes</span>(<span class="string">"your_image.jpg"</span>);
<span class="keyword">var</span> <span class="variable">imageBase64</span> <span class="operator">=</span> <span class="class">Convert</span>.<span class="function">ToBase64String</span>(<span class="variable">imageBytes</span>);
<span class="keyword">var</span> <span class="variable">payload</span> <span class="operator">=</span> <span class="keyword">new</span> {
<span class="property">image</span> = <span class="variable">imageBase64</span>,
<span class="property">confidence_threshold</span> = <span class="number">0.25</span>,
<span class="property">iou_threshold</span> = <span class="number">0.45</span>,
<span class="property">return_annotated_image</span> = <span class="keyword">true</span>
};
<span class="keyword">var</span> <span class="variable">json</span> <span class="operator">=</span> <span class="class">JsonConvert</span>.<span class="function">SerializeObject</span>(<span class="variable">payload</span>);
<span class="keyword">var</span> <span class="variable">content</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="function">StringContent</span>(<span class="variable">json</span>, <span class="class">Encoding</span>.<span class="property">UTF8</span>, <span class="string">"application/json"</span>);
<span class="keyword">var</span> <span class="variable">response</span> <span class="operator">=</span> <span class="keyword">await</span> <span class="variable">client</span>.<span class="function">PostAsync</span>(
<span class="string">"https://seamo-ai-fishapi.hf.space/api/v1/detect"</span>,
<span class="variable">content</span>
);
<span class="keyword">var</span> <span class="variable">result</span> <span class="operator">=</span> <span class="keyword">await</span> <span class="variable">response</span>.<span class="property">Content</span>.<span class="function">ReadAsStringAsync</span>();
<span class="class">Console</span>.<span class="function">WriteLine</span>(<span class="variable">result</span>);</pre>
</div>
</div>
<!-- Response Tab -->
<div class="tab-content" id="response-tab">
<div class="response-demo">
<div class="response-title">Example API Response</div>
<div class="response-description">
Actual response from testing with a marine image - detected <strong>8 marine species</strong> in 1.79 seconds:
</div>
<div class="detection-summary">
<div class="detection-item">
<span class="species-name">Sebastolobus (Rockfish)</span>
<span class="confidence-badge confidence-high">86.7%</span>
</div>
<div class="detection-item">
<span class="species-name">Octocorallia (Soft Coral)</span>
<span class="confidence-badge confidence-medium">69.7%</span>
</div>
<div class="detection-item">
<span class="species-name">Psolus squamatus (Sea Cucumber)</span>
<span class="confidence-badge confidence-medium">66.3%</span>
</div>
</div>
</div>
<div class="code-section">
<div class="code-header">
<span class="code-title">JSON Response</span>
<button class="copy-button" onclick="copyCode('response-code')">Copy</button>
</div>
<pre class="code-block" id="response-code">{
<span class="json-key">"detections"</span>: [
{
<span class="json-key">"class_id"</span>: <span class="json-number">3</span>,
<span class="json-key">"class_name"</span>: <span class="json-string">"Sebastolobus"</span>,
<span class="json-key">"confidence"</span>: <span class="json-number">0.8674</span>,
<span class="json-key">"bbox"</span>: {
<span class="json-key">"x"</span>: <span class="json-number">179.4</span>, <span class="json-key">"y"</span>: <span class="json-number">282.2</span>,
<span class="json-key">"width"</span>: <span class="json-number">129.7</span>, <span class="json-key">"height"</span>: <span class="json-number">71.0</span>
}
},
{
<span class="json-key">"class_id"</span>: <span class="json-number">16</span>,
<span class="json-key">"class_name"</span>: <span class="json-string">"Octocorallia"</span>,
<span class="json-key">"confidence"</span>: <span class="json-number">0.6969</span>,
<span class="json-key">"bbox"</span>: { <span class="comment">/* coordinates */</span> }
}
<span class="comment">// ... 6 more detections</span>
],
<span class="json-key">"annotated_image"</span>: <span class="json-string">"base64_encoded_image_with_boxes"</span>,
<span class="json-key">"processing_time"</span>: <span class="json-number">1.79</span>,
<span class="json-key">"model_info"</span>: {
<span class="json-key">"model_name"</span>: <span class="json-string">"marina-benthic-33k"</span>,
<span class="json-key">"total_classes"</span>: <span class="json-number">691</span>,
<span class="json-key">"device"</span>: <span class="json-string">"cpu"</span>
},
<span class="json-key">"image_dimensions"</span>: {
<span class="json-key">"width"</span>: <span class="json-number">714</span>, <span class="json-key">"height"</span>: <span class="json-number">486</span>
}
}</pre>
</div>
</div>
</div>
<!-- Documentation Footer -->
<div class="docs-footer">
<div class="info-grid">
<div class="info-card">
<h4>Request Parameters</h4>
<ul class="info-list">
<li><strong>image</strong> (required): Base64 encoded image data</li>
<li><strong>confidence_threshold</strong>: Minimum confidence (0.0-1.0, default: 0.25)</li>
<li><strong>iou_threshold</strong>: IoU threshold (0.0-1.0, default: 0.45)</li>
<li><strong>return_annotated_image</strong>: Return annotated image (boolean, default: true)</li>
</ul>
</div>
<div class="info-card">
<h4>Response Format</h4>
<ul class="info-list">
<li><strong>detections</strong>: Array of detected species with bounding boxes</li>
<li><strong>processing_time</strong>: Time taken for inference in seconds</li>
<li><strong>model_info</strong>: Information about the AI model used</li>
<li><strong>image_dimensions</strong>: Original image width and height</li>
</ul>
</div>
<div class="info-card">
<h4>Model Information</h4>
<ul class="info-list">
<li><strong>Model</strong>: marina-benthic-33k</li>
<li><strong>Species</strong>: 691 marine species supported</li>
<li><strong>Performance</strong>: ~2 seconds average processing</li>
<li><strong>Accuracy</strong>: High precision bounding boxes</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script src="/static/js/dashboard.js"></script>
{% endblock %}