File size: 3,279 Bytes
821b0e4
 
 
 
 
c72cb42
 
821b0e4
 
477faa1
 
821b0e4
 
 
 
 
 
 
 
 
 
 
a7a3116
 
821b0e4
 
a7a3116
 
 
 
 
9bb466d
a7a3116
 
821b0e4
a7a3116
821b0e4
a7a3116
 
821b0e4
 
 
 
 
 
 
 
149db23
821b0e4
 
 
 
 
 
 
 
 
a7a3116
821b0e4
 
 
a7a3116
821b0e4
 
a7a3116
821b0e4
 
 
 
 
 
477faa1
c72cb42
693f001
c72cb42
 
 
693f001
c72cb42
c44207c
 
c72cb42
c44207c
 
c72cb42
 
 
 
 
 
 
693f001
c72cb42
 
 
 
 
 
 
 
821b0e4
477faa1
821b0e4
 
149db23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// server.js
import express from "express";
import { Client } from "@gradio/client";
import dotenv from "dotenv";
import fetch from "node-fetch";
import multer from "multer";
const upload = multer();

dotenv.config();

const app = express();
const PORT = process.env.PORT || 7860;
const HF_TOKEN = process.env.HF_TOKEN;

if (!HF_TOKEN) {
  console.error("HF_TOKEN is not set in environment variables!");
  process.exit(1);
}

app.use(express.json({ limit: "10mb" }));

app.post("/api/proxy", async (req, res) => {
  let { fn, args } = req.body;
  
  if (!fn) return res.status(400).json({ error: "Missing 'fn' in request body" });

  // THE FIX: Scrub the 'args' object clean before passing it to Gradio.
  // If your frontend accidentally sent 'read_token' in the payload, this deletes it.
  if (args && typeof args === 'object' && !Array.isArray(args)) {
    delete args.read_token;
    delete args.hf_token;
    delete args.write_token;
  }

  try {
    // Auth is handled cleanly right here
    const client = await Client.connect("pockit-cloud/main", { hf_token: HF_TOKEN });
    
    // Now 'args' only contains the actual model inputs
    const result = await client.predict(fn, args);
    res.json({ data: result.data });
  } catch (err) {
    console.error("Proxy error:", err);
    res.status(500).json({ error: "Proxy call failed", details: err.message });
  }
});

// Download endpoint
app.get("/api/download", async (req, res) => {
  const { file } = req.query;
  if (!file) return res.status(400).json({ error: "Missing 'file' query param" });

  const url = `https://huggingface.co/datasets/${file}`;
  try {
    const response = await fetch(url, {
      headers: { Authorization: `Bearer ${HF_TOKEN}` },
    });
    
    if (!response.ok) {
      return res.status(response.status).json({ error: "File fetch failed" });
    }
    
    res.setHeader("Content-Disposition", `attachment; filename=\"${file.split("/").pop()}\"`);
    res.setHeader("Content-Type", response.headers.get("content-type") || "application/octet-stream");
    
    response.body.pipe(res);
  } catch (err) {
    console.error("Download error:", err);
    res.status(500).json({ error: "Download failed", details: err.message });
  }
});

app.post("/api/upload", upload.single("file"), async (req, res) => {
  const { user_id, password } = req.body;
  if (!req.file || !user_id || !password) {
    return res.status(400).json({ error: "Missing file, user_id, or password" });
  }
  const custom_name = req.file.originalname; // Required - use filename to avoid "blob"
  const fileData = {
    data: [new Uint8Array(req.file.buffer)],
    orig_name: req.file.originalname,
    size: req.file.size,
    mime_type: req.file.mimetype,
    is_stream: false
  };
  try {
    const client = await Client.connect("pockit-cloud/main", { hf_token: HF_TOKEN });
    const result = await client.predict("/upload_file_secure", { 
      user_id, 
      password, 
      filepath: fileData,
      custom_name
    });
    res.json({ data: result.data });
  } catch (err) {
    console.error("Upload error:", err);
    res.status(500).json({ error: "Upload failed", details: err.message });
  }
});

app.use(express.static("."));

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});