yellow60852 commited on
Commit
99c0c40
·
verified ·
1 Parent(s): e861665

Upload api.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. api.py +84 -0
api.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import tempfile
3
+ import torch
4
+ import torchaudio
5
+ import numpy as np
6
+ from fastapi import FastAPI, UploadFile, File, Header, HTTPException, status
7
+ from funasr import AutoModel
8
+ from funasr.utils.postprocess_utils import rich_transcription_postprocess
9
+
10
+ app = FastAPI(title="SenseVoice ASR API")
11
+
12
+ # Auth Token (default myLinuxTypeless888)
13
+ AUTH_TOKEN = os.environ.get("AUTH_TOKEN", "myLinuxTypeless888")
14
+
15
+ # Model configurations
16
+ MODEL_CACHE_DIR = "./models"
17
+ SENSE_VOICE_SMALL_LOCAL_PATH = os.path.join(MODEL_CACHE_DIR, "SenseVoiceSmall")
18
+ VAD_MODEL_LOCAL_PATH = os.path.join(MODEL_CACHE_DIR, "fsmn-vad")
19
+
20
+ # Device config (force CPU for free HF Space tier)
21
+ device = "cpu"
22
+
23
+ print(f"Loading SenseVoice model on {device}...")
24
+ model = AutoModel(
25
+ model=SENSE_VOICE_SMALL_LOCAL_PATH,
26
+ trust_remote_code=False,
27
+ vad_model=VAD_MODEL_LOCAL_PATH,
28
+ vad_kwargs={"max_single_segment_time": 30000},
29
+ device=device,
30
+ disable_update=True,
31
+ hub="hf",
32
+ )
33
+ print("Model loaded successfully.")
34
+
35
+ @app.post("/transcribe")
36
+ async def transcribe(
37
+ file: UploadFile = File(...),
38
+ authorization: str = Header(None)
39
+ ):
40
+ # Verify auth token
41
+ if not authorization:
42
+ raise HTTPException(
43
+ status_code=status.HTTP_401_UNAUTHORIZED,
44
+ detail="Authorization header missing"
45
+ )
46
+
47
+ parts = authorization.split()
48
+ if len(parts) != 2 or parts[0].lower() != "bearer" or parts[1] != AUTH_TOKEN:
49
+ raise HTTPException(
50
+ status_code=status.HTTP_401_UNAUTHORIZED,
51
+ detail="Invalid authorization token"
52
+ )
53
+
54
+ # Save incoming audio stream to a temporary WAV file
55
+ with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp:
56
+ tmp.write(await file.read())
57
+ audio_path = tmp.name
58
+
59
+ try:
60
+ # Generate transcription
61
+ res = model.generate(
62
+ input=audio_path,
63
+ cache={},
64
+ language="auto",
65
+ use_itn=True,
66
+ batch_size_s=60,
67
+ merge_vad=True,
68
+ )
69
+
70
+ text = rich_transcription_postprocess(res[0]["text"])
71
+ return {"text": text}
72
+
73
+ except Exception as e:
74
+ raise HTTPException(
75
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
76
+ detail=f"Transcription error: {str(e)}"
77
+ )
78
+ finally:
79
+ if os.path.exists(audio_path):
80
+ os.unlink(audio_path)
81
+
82
+ @app.get("/health")
83
+ def health():
84
+ return {"status": "ok"}