Download server.py from endurasolution/aksharakuppy-transliteration: direct link, hf CLI and curl.
- Browser
- Download file 3.92 kB
-
https://huggingface.co/endurasolution/aksharakuppy-transliteration/resolve/main/server.py
- Command line
-
hf download hf://endurasolution/aksharakuppy-transliteration/server.py
-
curl -L -o server.py https://huggingface.co/endurasolution/aksharakuppy-transliteration/resolve/main/server.py
3.92 kB
| from fastapi import FastAPI | |
| from fastapi.responses import HTMLResponse | |
| from ime import IME | |
| app = FastAPI() | |
| ime = IME() | |
| def suggest(q: str, k: int = 5): | |
| return {"input": q, "suggestions": ime.suggest(q, k=k)} | |
| PAGE = """ | |
| <!doctype html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title>Manglish → Malayalam IME</title> | |
| <style> | |
| :root{ | |
| --bg:#0f1115; --panel:#171a21; --panel2:#1e222b; | |
| --text:#e6e8ec; --muted:#8b93a1; --accent:#4f8cff; | |
| --accent-soft:#22314f; --border:#2a2f3a; --chip:#232833; | |
| } | |
| *{box-sizing:border-box} | |
| body{ | |
| font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif; | |
| background:var(--bg); color:var(--text); | |
| margin:0; min-height:100vh; | |
| display:flex; align-items:flex-start; justify-content:center; | |
| } | |
| .wrap{width:100%; max-width:680px; padding:56px 20px} | |
| h1{font-size:22px; font-weight:600; margin:0 0 4px} | |
| .sub{color:var(--muted); font-size:14px; margin:0 0 28px} | |
| #out{ | |
| font-size:26px; line-height:1.5; min-height:52px; | |
| background:var(--panel); border:1px solid var(--border); | |
| border-radius:12px; padding:14px 16px; margin-bottom:16px; | |
| word-break:break-word; | |
| } | |
| #out:empty::before{content:"Your Malayalam text appears here…"; color:var(--muted); font-size:17px} | |
| input{ | |
| width:100%; font-size:22px; padding:14px 16px; | |
| background:var(--panel2); color:var(--text); | |
| border:1px solid var(--border); border-radius:12px; outline:none; | |
| transition:border-color .15s; | |
| } | |
| input:focus{border-color:var(--accent)} | |
| input::placeholder{color:var(--muted)} | |
| #sug{margin-top:12px; min-height:52px; display:flex; flex-wrap:wrap; gap:8px} | |
| .s{ | |
| padding:9px 16px; background:var(--chip); color:var(--text); | |
| border:1px solid var(--border); border-radius:10px; | |
| font-size:22px; cursor:pointer; user-select:none; | |
| transition:background .12s, border-color .12s; | |
| } | |
| .s:hover{background:#2b313d} | |
| .s:first-child{background:var(--accent-soft); border-color:var(--accent)} | |
| .hint{color:var(--muted); font-size:13px; margin-top:18px; line-height:1.6} | |
| .hint b{color:var(--text); font-weight:600} | |
| </style> | |
| </head> | |
| <body> | |
| <div class="wrap"> | |
| <h1>Manglish → Malayalam IME</h1> | |
| <p class="sub">Type Malayalam using English letters.</p> | |
| <div id="out"></div> | |
| <input id="inp" placeholder="type manglish… e.g. ente veedu" autocomplete="off" autofocus> | |
| <div id="sug"></div> | |
| <p class="hint"> | |
| <b>space</b> or <b>enter</b> = accept first suggestion · | |
| <b>click</b> a chip to pick · | |
| <b>backspace</b> on empty input deletes last word | |
| </p> | |
| </div> | |
| <script> | |
| const inp=document.getElementById('inp'), | |
| sug=document.getElementById('sug'), | |
| out=document.getElementById('out'); | |
| let timer=null,current=[],ctr=0; | |
| inp.addEventListener('input',()=>{clearTimeout(timer);timer=setTimeout(fetchSug,110)}); | |
| async function fetchSug(){ | |
| const q=inp.value.trim(); | |
| if(!q){sug.innerHTML='';current=[];return} | |
| const my=++ctr; | |
| try{ | |
| const r=await fetch('/suggest?q='+encodeURIComponent(q)); | |
| const j=await r.json(); | |
| if(my!==ctr)return; // ignore stale responses | |
| current=j.suggestions; | |
| sug.innerHTML=current.map(s=>`<span class="s">${s}</span>`).join(''); | |
| [...sug.children].forEach((el,i)=>el.onclick=()=>pick(current[i])); | |
| }catch(e){/* ignore */} | |
| } | |
| function pick(s){ | |
| out.textContent+=s+' '; | |
| inp.value='';sug.innerHTML='';current=[];inp.focus(); | |
| } | |
| inp.addEventListener('keydown',e=>{ | |
| if((e.key===' '||e.key==='Enter')&¤t.length){ | |
| e.preventDefault();pick(current[0]); | |
| }else if(e.key==='Backspace'&&!inp.value){ | |
| e.preventDefault(); | |
| out.textContent=out.textContent.trimEnd().split(' ').slice(0,-1).join(' '); | |
| if(out.textContent)out.textContent+=' '; | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> | |
| """ | |
| def index(): | |
| return PAGE |