fomext commited on
Commit
8b80b8c
·
verified ·
1 Parent(s): aa186de

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +134 -18
app.py CHANGED
@@ -1,12 +1,16 @@
1
- from fastapi import FastAPI
 
 
 
 
 
 
2
 
3
  import audiocraft
4
- print("Audiocraft version:", audiocraft.__version__)
5
-
6
  from audiocraft.models import MusicGen
7
  from audiocraft.data.audio import audio_write
8
- import uuid
9
- import os
10
 
11
  app = FastAPI()
12
 
@@ -17,28 +21,140 @@ os.makedirs(OUTPUT_DIR, exist_ok=True)
17
  print("Loading MusicGen model...")
18
  model = MusicGen.get_pretrained(MODEL_NAME)
19
  model.set_generation_params(
20
- duration=30, # seconds
21
  temperature=1.0,
22
  top_k=250,
23
  top_p=0.0
24
  )
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  @app.post("/generate")
27
  async def generate(prompt: str):
28
- wav = model.generate([prompt])[0]
29
 
30
- filename = f"{uuid.uuid4().hex}"
31
- path = os.path.join(OUTPUT_DIR, filename)
 
 
 
 
32
 
33
- audio_write(
34
- path,
35
- wav.cpu(),
36
- model.sample_rate,
37
- strategy="loudness",
38
- loudness_compressor=True
39
- )
40
 
41
  return {
42
- "prompt": prompt,
43
- "file": f"{filename}.wav"
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, BackgroundTasks, HTTPException
2
+ from fastapi.responses import FileResponse
3
+ import threading
4
+ import queue
5
+ import uuid
6
+ import os
7
+ import time
8
 
9
  import audiocraft
 
 
10
  from audiocraft.models import MusicGen
11
  from audiocraft.data.audio import audio_write
12
+
13
+ print("Audiocraft version:", audiocraft.__version__)
14
 
15
  app = FastAPI()
16
 
 
21
  print("Loading MusicGen model...")
22
  model = MusicGen.get_pretrained(MODEL_NAME)
23
  model.set_generation_params(
24
+ duration=30,
25
  temperature=1.0,
26
  top_k=250,
27
  top_p=0.0
28
  )
29
 
30
+ # -------------------------
31
+ # Job system (in-memory)
32
+ # -------------------------
33
+
34
+ job_queue = queue.Queue()
35
+ jobs = {} # job_id -> metadata
36
+
37
+
38
+ class JobStatus:
39
+ QUEUED = "queued"
40
+ PROCESSING = "processing"
41
+ COMPLETED = "completed"
42
+ FAILED = "failed"
43
+
44
+
45
+ def worker():
46
+ """Background worker that processes queued jobs"""
47
+ while True:
48
+ job_id = job_queue.get()
49
+ job = jobs.get(job_id)
50
+
51
+ if not job:
52
+ job_queue.task_done()
53
+ continue
54
+
55
+ try:
56
+ jobs[job_id]["status"] = JobStatus.PROCESSING
57
+
58
+ wav = model.generate([job["prompt"]])[0]
59
+
60
+ filename = f"{job_id}.wav"
61
+ path = os.path.join(OUTPUT_DIR, filename)
62
+
63
+ audio_write(
64
+ path,
65
+ wav.cpu(),
66
+ model.sample_rate,
67
+ strategy="loudness",
68
+ loudness_compressor=True
69
+ )
70
+
71
+ jobs[job_id].update({
72
+ "status": JobStatus.COMPLETED,
73
+ "file_path": path
74
+ })
75
+
76
+ except Exception as e:
77
+ jobs[job_id].update({
78
+ "status": JobStatus.FAILED,
79
+ "error": str(e)
80
+ })
81
+
82
+ job_queue.task_done()
83
+
84
+
85
+ # Start worker thread
86
+ threading.Thread(target=worker, daemon=True).start()
87
+
88
+ # -------------------------
89
+ # API endpoints
90
+ # -------------------------
91
+
92
  @app.post("/generate")
93
  async def generate(prompt: str):
94
+ job_id = uuid.uuid4().hex
95
 
96
+ jobs[job_id] = {
97
+ "status": JobStatus.QUEUED,
98
+ "prompt": prompt,
99
+ "created_at": time.time(),
100
+ "file_path": None
101
+ }
102
 
103
+ job_queue.put(job_id)
 
 
 
 
 
 
104
 
105
  return {
106
+ "job_id": job_id,
107
+ "status_url": f"/status/{job_id}"
108
  }
109
+
110
+
111
+ @app.get("/status/{job_id}")
112
+ async def status(job_id: str):
113
+ job = jobs.get(job_id)
114
+
115
+ if not job:
116
+ raise HTTPException(status_code=404, detail="Job not found")
117
+
118
+ response = {
119
+ "job_id": job_id,
120
+ "status": job["status"]
121
+ }
122
+
123
+ if job["status"] == JobStatus.COMPLETED:
124
+ response["download_url"] = f"/download/{job_id}"
125
+
126
+ if job["status"] == JobStatus.FAILED:
127
+ response["error"] = job.get("error")
128
+
129
+ return response
130
+
131
+
132
+ def delete_file(path: str, delay: int = 10):
133
+ """Deletes file after response is sent"""
134
+ time.sleep(delay)
135
+ if os.path.exists(path):
136
+ os.remove(path)
137
+
138
+
139
+ @app.get("/download/{job_id}")
140
+ async def download(job_id: str, background_tasks: BackgroundTasks):
141
+ job = jobs.get(job_id)
142
+
143
+ if not job:
144
+ raise HTTPException(status_code=404, detail="Job not found")
145
+
146
+ if job["status"] != JobStatus.COMPLETED:
147
+ raise HTTPException(status_code=400, detail="Job not completed")
148
+
149
+ path = job["file_path"]
150
+
151
+ if not path or not os.path.exists(path):
152
+ raise HTTPException(status_code=404, detail="File not found")
153
+
154
+ background_tasks.add_task(delete_file, path)
155
+
156
+ return FileResponse(
157
+ path,
158
+ media_type="audio/wav",
159
+ filename=os.path.basename(path)
160
+ )