Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>AI Summarizer</title> | |
| <!-- Bootstrap CSS --> | |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> | |
| <style> | |
| body { background-color: #f8f9fa; padding-top: 50px; } | |
| .container { max-width: 900px; } | |
| .card { box-shadow: 0 4px 6px rgba(0,0,0,0.1); border: none; } | |
| .loader { display: none; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="text-center mb-5"> | |
| <h1 class="display-5 fw-bold text-primary">Summarization Inference</h1> | |
| <p class="lead">Running via Flask Blueprint & HuggingFace Transformers</p> | |
| </div> | |
| <div class="row"> | |
| <!-- Input Column --> | |
| <div class="col-md-6 mb-4"> | |
| <div class="card h-100"> | |
| <div class="card-header bg-primary text-white">Input Text</div> | |
| <div class="card-body"> | |
| <div class="mb-3"> | |
| <input class="form-control" type="password" id="hfToken" rows="10" placeholder="Huggingface Token or .env"> | |
| </div> | |
| <div class="mb-3"> | |
| <label for="modelSelect" class="form-label">Choose Model</label> | |
| <select class="form-select" id="modelSelect"> | |
| <option value="custom" selected>Custom</option> | |
| <option value="facebook/bart-large-cnn">facebook/bart-large-cnn</option> | |
| <option value="google/pegasus-xsum">google/pegasus-xsum</option> | |
| <option value="sshleifer/distilbart-cnn-12-6">sshleifer/distilbart-cnn-12-6 (Faster)</option> | |
| </select> | |
| <input class="form-control" id="inputModel" rows="10" placeholder="custom HF model id user/model"> | |
| </div> | |
| <div class="mb-3"> | |
| <label class="small">Temperature: <span id="temp-val" class="fw-bold">0.7</span></label> | |
| <input type="range" class="form-range" id="temperature" min="0.1" max="1.5" value="0.7" step="0.1" oninput="document.getElementById('temp-val').innerText = this.value"> | |
| <label class="small">Top K: <span id="topk-val" class="fw-bold">50</span></label> | |
| <input type="range" class="form-range" id="topk" min="1" max="100" value="50" step="1" oninput="document.getElementById('topk-val').innerText = this.value"> | |
| </div> | |
| <div class="mb-3"> | |
| <label for="inputText" class="form-label">Text to Summarize</label> | |
| <textarea class="form-control" id="inputText" rows="10" placeholder="Paste your long text here..."></textarea> | |
| </div> | |
| <button id="submitBtn" class="btn btn-primary w-100">Summarize</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Output Column --> | |
| <div class="col-md-6 mb-4"> | |
| <div class="card h-100"> | |
| <div class="card-header bg-success text-white">Summary Result</div> | |
| <div class="card-body position-relative"> | |
| <!-- Loading Spinner --> | |
| <div id="loader" class="loader position-absolute top-50 start-50 translate-middle text-center"> | |
| <div class="spinner-border text-primary" role="status"></div> | |
| <p class="mt-2">Loading model &<br>generating...</p> | |
| </div> | |
| <!-- Output Text --> | |
| <div id="resultContainer"> | |
| <p class="text-muted" id="placeholderText">The summary will appear here.</p> | |
| <p id="outputText" class="fw-medium"></p> | |
| </div> | |
| <!-- Error Alert --> | |
| <div id="errorAlert" class="alert alert-danger d-none mt-3"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| document.getElementById('submitBtn').addEventListener('click', async () => { | |
| const text = document.getElementById('inputText').value; | |
| const model = document.getElementById('modelSelect').value; | |
| const outputText = document.getElementById('outputText'); | |
| const placeholder = document.getElementById('placeholderText'); | |
| const loader = document.getElementById('loader'); | |
| const resultContainer = document.getElementById('resultContainer'); | |
| const errorAlert = document.getElementById('errorAlert'); | |
| const inputModel = document.getElementById('inputModel').value; | |
| const hfToken = document.getElementById('hfToken'); | |
| const temperature = document.getElementById('temperature').value; | |
| const topk = document.getElementById('topk').value; | |
| console.log(model) | |
| if (model === 'custom') { | |
| modelOut = inputModel; | |
| } else { | |
| modelOut = model; | |
| } | |
| if (!text.trim()) { | |
| alert("Please enter some text!"); | |
| return; | |
| } | |
| // UI Updates | |
| loader.style.display = 'block'; | |
| resultContainer.style.opacity = '0.3'; | |
| errorAlert.classList.add('d-none'); | |
| document.getElementById('submitBtn').disabled = true; | |
| try { | |
| const response = await fetch('/summarize/api/summarize', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ text: text, model_name: modelOut, hf_token: hfToken, temp: temperature, topk: topk }) | |
| }); | |
| const data = await response.json(); | |
| loader.style.display = 'none'; | |
| resultContainer.style.opacity = '1'; | |
| document.getElementById('submitBtn').disabled = false; | |
| if (response.ok) { | |
| placeholder.style.display = 'none'; | |
| outputText.innerText = data.output; | |
| } else { | |
| errorAlert.innerText = "Error: " + (data.error || "Unknown error"); | |
| errorAlert.classList.remove('d-none'); | |
| } | |
| } catch (err) { | |
| console.error(err); | |
| loader.style.display = 'none'; | |
| resultContainer.style.opacity = '1'; | |
| document.getElementById('submitBtn').disabled = false; | |
| errorAlert.innerText = "Network Error or Server Timeout"; | |
| errorAlert.classList.remove('d-none'); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> |