Gertie2013 commited on
Commit
f2db9c0
·
verified ·
1 Parent(s): 965de74

Create pages/api/generate.ts

Browse files
Files changed (1) hide show
  1. pages/api/generate.ts +100 -0
pages/api/generate.ts ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { NextApiRequest, NextApiResponse } from "next";
2
+ import { VALID_MODELS, validateModel, validateApiKey } from "../../lib/config";
3
+ import { getCachedGeneration, setCachedGeneration } from "../../lib/cache";
4
+ import type { GenerateRequestBody } from "../../lib/types";
5
+
6
+ export default async function handler(req: NextApiRequest, res: NextApiResponse) {
7
+ res.setHeader("Content-Type", "application/json");
8
+
9
+ if (req.method !== "POST") {
10
+ return res.status(405).json({ error: "Method not allowed" });
11
+ }
12
+
13
+ const hfApiKey = process.env.HF_API_KEY;
14
+ if (!validateApiKey(hfApiKey)) {
15
+ return res.status(500).json({ error: "Invalid or missing Hugging Face API key" });
16
+ }
17
+
18
+ const model = VALID_MODELS.ACE_STEP;
19
+ if (!validateModel(model)) {
20
+ return res.status(500).json({ error: "Invalid model configuration" });
21
+ }
22
+
23
+ let body: GenerateRequestBody;
24
+ try {
25
+ body = req.body as GenerateRequestBody;
26
+ } catch {
27
+ return res.status(400).json({ error: "Invalid JSON body" });
28
+ }
29
+
30
+ const {
31
+ stylePrompt,
32
+ lyricPrompt = "",
33
+ voice = "Random",
34
+ durationSeconds,
35
+ } = body;
36
+
37
+ if (!stylePrompt || typeof stylePrompt !== "string") {
38
+ return res.status(400).json({ error: "stylePrompt is required" });
39
+ }
40
+
41
+ const duration =
42
+ typeof durationSeconds === "number"
43
+ ? Math.min(240, Math.max(30, durationSeconds))
44
+ : Math.floor(Math.random() * (240 - 30 + 1)) + 30;
45
+
46
+ const cacheKey = JSON.stringify({ stylePrompt, lyricPrompt, voice, duration });
47
+ const cached = getCachedGeneration(cacheKey);
48
+ if (cached) {
49
+ return res.status(200).json({ cached: true, ...cached });
50
+ }
51
+
52
+ try {
53
+ const payload = {
54
+ inputs: {
55
+ text: `${stylePrompt}\n${lyricPrompt}`,
56
+ voice,
57
+ duration,
58
+ },
59
+ };
60
+
61
+ const hfUrl = `https://api-inference.huggingface.co/models/${encodeURIComponent(model)}`;
62
+
63
+ const response = await fetch(hfUrl, {
64
+ method: "POST",
65
+ headers: {
66
+ Authorization: `Bearer ${hfApiKey}`,
67
+ "Content-Type": "application/json",
68
+ Accept: "application/json",
69
+ },
70
+ body: JSON.stringify(payload),
71
+ });
72
+
73
+ if (!response.ok) {
74
+ const errText = await response.text().catch(() => "");
75
+ return res.status(response.status).json({
76
+ error: "Model request failed",
77
+ details: errText || response.statusText,
78
+ });
79
+ }
80
+
81
+ const result = await response.json();
82
+
83
+ const data = {
84
+ cached: false,
85
+ model,
86
+ duration,
87
+ voice,
88
+ result,
89
+ };
90
+
91
+ setCachedGeneration(cacheKey, data);
92
+
93
+ return res.status(200).json(data);
94
+ } catch (e: any) {
95
+ return res.status(500).json({
96
+ error: "Unexpected error during generation",
97
+ details: e?.message ?? "Unknown error",
98
+ });
99
+ }
100
+ }