uploadv2 / server.js
marriedtermiteblyi's picture
Update server.js
da6bb80 verified
raw
history blame
3.53 kB
// @ts-nocheck
import express from 'express';
import cors from 'cors';
import multer from 'multer';
import { commit } from '@huggingface/hub'; // Use 'commit' for batch operations
import path from 'path';
import { fileURLToPath } from 'url';
// Fix __dirname for ES Modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
// Hugging Face Spaces requires port 7860
const port = process.env.PORT || 7860;
// Middleware
app.use(cors());
app.use(express.json());
// Configure Multer for memory storage
// No limit on file count here, but we limit payload size via express/nginx usually
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });
// SERVER CONFIGURATION
const SERVER_CONFIG = {
TOKEN: process.env.HF_TOKEN || '',
REPO: process.env.HF_REPO || 'TwanAPI/DataTwan',
TYPE: 'dataset'
};
// --- API ROUTES ---
// Batch Upload Endpoint
// Accepts multiple files in the 'files' field
app.post('/api/upload', upload.array('files'), async (req, res) => {
try {
const files = req.files;
// req.body.paths can be a string (if 1 file) or array (if multiple)
// We normalize it to an array
const paths = [].concat(req.body.paths || []);
if (!files || files.length === 0) {
return res.status(400).json({ error: 'No files provided' });
}
if (files.length !== paths.length) {
return res.status(400).json({ error: 'Mismatch between file count and path count' });
}
// Security Check
if (!SERVER_CONFIG.TOKEN) {
console.error('[SERVER] Upload Failed: HF_TOKEN missing');
return res.status(500).json({ error: 'Server misconfiguration: HF_TOKEN secret is missing.' });
}
console.log(`[SERVER] Processing batch of ${files.length} files...`);
// Prepare operations for Hugging Face 'commit'
const operations = files.map((file, index) => ({
operation: 'addOrUpdate',
path: paths[index],
content: new Blob([file.buffer])
}));
// Execute single commit for all files
const response = await commit({
credentials: {
accessToken: SERVER_CONFIG.TOKEN,
},
repo: {
type: SERVER_CONFIG.TYPE,
name: SERVER_CONFIG.REPO
},
operations: operations,
title: `Upload batch of ${files.length} files via DataTwan`
});
const commitHash = response.oid; // 'commit' returns { oid: string, ... }
const urlPrefix = "https://huggingface.co/datasets";
// Generate public URLs for response
const urls = paths.map(p => `${urlPrefix}/${SERVER_CONFIG.REPO}/blob/${commitHash}/${p}`);
console.log(`[SERVER] Batch Success: ${files.length} files committed (Hash: ${commitHash})`);
res.json({
success: true,
count: files.length,
urls: urls
});
} catch (error) {
console.error('[SERVER] Batch Upload Error:', error);
res.status(500).json({
success: false,
error: error.message || 'Internal Server Error'
});
}
});
// --- SERVE FRONTEND (Production) ---
app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
// Start Server
app.listen(port, () => {
console.log(`--------------------------------------------------`);
console.log(`✅ Server running on port ${port}`);
console.log(` Target Repo: ${SERVER_CONFIG.REPO}`);
console.log(`--------------------------------------------------`);
});