4cko commited on
Commit ยท
7ad9382
1
Parent(s): 60d7455
/home/codespace
Browse files- .env.example +7 -0
- .gitignore +13 -0
- QUICKSTART.md +23 -1
- README.md +33 -4
- examples/env-upload.sh +47 -0
- ge/.gitattributes +35 -0
- ge/README.md +10 -0
- server.js +11 -6
.env.example
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Server Configuration
|
| 2 |
+
PORT=3000
|
| 3 |
+
NODE_ENV=development
|
| 4 |
+
|
| 5 |
+
# Hugging Face Configuration (opsional - bisa dikirim saat request atau set di sini)
|
| 6 |
+
HF_TOKEN=your_huggingface_token_here
|
| 7 |
+
HF_REPO_ID=username/dataset-name
|
.gitignore
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules/
|
| 2 |
+
uploads/
|
| 3 |
+
.env
|
| 4 |
+
.env.local
|
| 5 |
+
.DS_Store
|
| 6 |
+
*.log
|
| 7 |
+
npm-debug.log*
|
| 8 |
+
yarn-debug.log*
|
| 9 |
+
yarn-error.log*
|
| 10 |
+
.vscode/
|
| 11 |
+
.idea/
|
| 12 |
+
dist/
|
| 13 |
+
build/
|
QUICKSTART.md
CHANGED
|
@@ -18,7 +18,29 @@ Server akan berjalan di `http://localhost:3000`
|
|
| 18 |
|
| 19 |
### 3. Test Upload
|
| 20 |
|
| 21 |
-
####
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
```bash
|
| 23 |
# Siapkan file test
|
| 24 |
echo "id,name,value" > test.csv
|
|
|
|
| 18 |
|
| 19 |
### 3. Test Upload
|
| 20 |
|
| 21 |
+
#### Cara 1: Dengan Environment Variables (Recommended)
|
| 22 |
+
|
| 23 |
+
**Setup .env:**
|
| 24 |
+
```bash
|
| 25 |
+
# Copy dari .env.example
|
| 26 |
+
cp .env.example .env
|
| 27 |
+
|
| 28 |
+
# Edit .env dan set:
|
| 29 |
+
# HF_TOKEN=hf_your_token_here
|
| 30 |
+
# HF_REPO_ID=username/my-dataset
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
**Kemudian upload hanya dengan file:**
|
| 34 |
+
```bash
|
| 35 |
+
# cURL
|
| 36 |
+
curl -X POST http://localhost:3000/api/upload \
|
| 37 |
+
-F "file=@test.csv"
|
| 38 |
+
|
| 39 |
+
# atau
|
| 40 |
+
bash examples/env-upload.sh
|
| 41 |
+
```
|
| 42 |
+
|
| 43 |
+
#### Cara 2: Via cURL (Terminal)
|
| 44 |
```bash
|
| 45 |
# Siapkan file test
|
| 46 |
echo "id,name,value" > test.csv
|
README.md
CHANGED
|
@@ -8,8 +8,6 @@ app_port: 3000
|
|
| 8 |
pinned: false
|
| 9 |
---
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
# Vico - Hugging Face File Upload API
|
| 14 |
|
| 15 |
API Node.js untuk upload file ke Hugging Face Dataset dengan response format JSON.
|
|
@@ -72,12 +70,14 @@ Server akan berjalan di `http://localhost:3000`
|
|
| 72 |
|
| 73 |
**Required Fields:**
|
| 74 |
- `file` - File yang akan di-upload (form-data)
|
| 75 |
-
- `repo_id` - Hugging Face repo ID (format: `username/dataset-name`)
|
| 76 |
-
- `token` - Hugging Face API token
|
| 77 |
|
| 78 |
**Optional Fields:**
|
| 79 |
- `subfolder` - Subfolder dalam repository (default: root)
|
| 80 |
|
|
|
|
|
|
|
| 81 |
#### Contoh menggunakan cURL:
|
| 82 |
```bash
|
| 83 |
curl -X POST http://localhost:3000/api/upload \
|
|
@@ -163,6 +163,35 @@ async function uploadFile() {
|
|
| 163 |
}
|
| 164 |
```
|
| 165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
### 3. Response Format
|
| 167 |
|
| 168 |
#### โ
Sukses Upload (Status 200):
|
|
|
|
| 8 |
pinned: false
|
| 9 |
---
|
| 10 |
|
|
|
|
|
|
|
| 11 |
# Vico - Hugging Face File Upload API
|
| 12 |
|
| 13 |
API Node.js untuk upload file ke Hugging Face Dataset dengan response format JSON.
|
|
|
|
| 70 |
|
| 71 |
**Required Fields:**
|
| 72 |
- `file` - File yang akan di-upload (form-data)
|
| 73 |
+
- `repo_id` - Hugging Face repo ID (format: `username/dataset-name`) *atau set di .env*
|
| 74 |
+
- `token` - Hugging Face API token *atau set di .env*
|
| 75 |
|
| 76 |
**Optional Fields:**
|
| 77 |
- `subfolder` - Subfolder dalam repository (default: root)
|
| 78 |
|
| 79 |
+
**Catatan:** Jika `repo_id` dan `token` sudah di-set di `.env` (HF_REPO_ID dan HF_TOKEN), Anda tidak perlu mengirimnya di request. Nilai dari request akan override nilai di .env.
|
| 80 |
+
|
| 81 |
#### Contoh menggunakan cURL:
|
| 82 |
```bash
|
| 83 |
curl -X POST http://localhost:3000/api/upload \
|
|
|
|
| 163 |
}
|
| 164 |
```
|
| 165 |
|
| 166 |
+
#### Menggunakan Environment Variables (.env)
|
| 167 |
+
Jika sudah set `.env` dengan `HF_TOKEN` dan `HF_REPO_ID`, Anda bisa upload hanya dengan file:
|
| 168 |
+
|
| 169 |
+
**cURL:**
|
| 170 |
+
```bash
|
| 171 |
+
curl -X POST http://localhost:3000/api/upload \
|
| 172 |
+
-F "file=@/path/to/file.csv"
|
| 173 |
+
```
|
| 174 |
+
|
| 175 |
+
**Node.js:**
|
| 176 |
+
```javascript
|
| 177 |
+
const form = new FormData();
|
| 178 |
+
form.append('file', fs.createReadStream('file.csv'));
|
| 179 |
+
// repo_id dan token akan diambil dari .env
|
| 180 |
+
|
| 181 |
+
axios.post('http://localhost:3000/api/upload', form, {
|
| 182 |
+
headers: form.getHeaders()
|
| 183 |
+
}).then(res => console.log(res.data));
|
| 184 |
+
```
|
| 185 |
+
|
| 186 |
+
**Python:**
|
| 187 |
+
```python
|
| 188 |
+
files = {'file': open('file.csv', 'rb')}
|
| 189 |
+
# repo_id dan token akan diambil dari .env
|
| 190 |
+
|
| 191 |
+
r = requests.post('http://localhost:3000/api/upload', files=files)
|
| 192 |
+
print(r.json())
|
| 193 |
+
```
|
| 194 |
+
|
| 195 |
### 3. Response Format
|
| 196 |
|
| 197 |
#### โ
Sukses Upload (Status 200):
|
examples/env-upload.sh
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
# Contoh: Upload file menggunakan Environment Variables
|
| 4 |
+
#
|
| 5 |
+
# Setup:
|
| 6 |
+
# 1. Edit .env dan set HF_TOKEN dan HF_REPO_ID
|
| 7 |
+
# 2. Jalankan script ini
|
| 8 |
+
#
|
| 9 |
+
# Cara jalankan:
|
| 10 |
+
# chmod +x examples/env-upload.sh
|
| 11 |
+
# ./examples/env-upload.sh
|
| 12 |
+
|
| 13 |
+
echo "๐ Hugging Face Upload API - Environment Variables Example"
|
| 14 |
+
echo "=========================================================="
|
| 15 |
+
echo ""
|
| 16 |
+
|
| 17 |
+
# Setup file test
|
| 18 |
+
FILE_PATH="./examples/sample-data-env.csv"
|
| 19 |
+
|
| 20 |
+
if [ ! -f "$FILE_PATH" ]; then
|
| 21 |
+
echo "๐ Membuat file contoh..."
|
| 22 |
+
mkdir -p "$(dirname "$FILE_PATH")"
|
| 23 |
+
cat > "$FILE_PATH" << EOF
|
| 24 |
+
id,name,value,date
|
| 25 |
+
1,Alice,100,2024-01-01
|
| 26 |
+
2,Bob,200,2024-01-02
|
| 27 |
+
3,Charlie,300,2024-01-03
|
| 28 |
+
EOF
|
| 29 |
+
fi
|
| 30 |
+
|
| 31 |
+
echo "โ
File tersedia: $FILE_PATH"
|
| 32 |
+
echo ""
|
| 33 |
+
echo "๐ค Uploading file dengan environment variables..."
|
| 34 |
+
echo ""
|
| 35 |
+
|
| 36 |
+
# Upload file (repo_id dan token dari .env)
|
| 37 |
+
curl -X POST http://localhost:3000/api/upload \
|
| 38 |
+
-F "file=@$FILE_PATH" \
|
| 39 |
+
-H "Accept: application/json" | jq .
|
| 40 |
+
|
| 41 |
+
echo ""
|
| 42 |
+
echo "โ
Upload selesai!"
|
| 43 |
+
echo ""
|
| 44 |
+
echo "๐ก Catatan:"
|
| 45 |
+
echo " - Pastikan .env sudah diset dengan HF_TOKEN dan HF_REPO_ID"
|
| 46 |
+
echo " - Server akan menggunakan nilai dari .env jika tidak dikirim di request"
|
| 47 |
+
echo " - Bisa juga override dengan mengirim repo_id atau token di request"
|
ge/.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
ge/README.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: Ge
|
| 3 |
+
emoji: ๐
|
| 4 |
+
colorFrom: purple
|
| 5 |
+
colorTo: blue
|
| 6 |
+
sdk: docker
|
| 7 |
+
pinned: false
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
server.js
CHANGED
|
@@ -68,15 +68,20 @@ app.post('/api/upload', upload.single('file'), async (req, res) => {
|
|
| 68 |
|
| 69 |
const { repo_id, token, subfolder } = req.body;
|
| 70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
// Validasi required fields
|
| 72 |
-
if (!
|
| 73 |
// Hapus file yang sudah di-upload
|
| 74 |
fs.unlinkSync(req.file.path);
|
| 75 |
|
| 76 |
return res.status(400).json({
|
| 77 |
success: false,
|
| 78 |
-
error: 'repo_id dan token diperlukan',
|
| 79 |
-
required_fields: ['repo_id', 'token']
|
|
|
|
| 80 |
});
|
| 81 |
}
|
| 82 |
|
|
@@ -84,8 +89,8 @@ app.post('/api/upload', upload.single('file'), async (req, res) => {
|
|
| 84 |
const result = await hfUploader.uploadFile({
|
| 85 |
filePath: req.file.path,
|
| 86 |
fileName: req.file.originalname,
|
| 87 |
-
repoId:
|
| 88 |
-
token:
|
| 89 |
subfolder: subfolder || ''
|
| 90 |
});
|
| 91 |
|
|
@@ -98,7 +103,7 @@ app.post('/api/upload', upload.single('file'), async (req, res) => {
|
|
| 98 |
data: {
|
| 99 |
file_name: req.file.originalname,
|
| 100 |
file_size: req.file.size,
|
| 101 |
-
repo_id:
|
| 102 |
path_prefix: '/u/',
|
| 103 |
subfolder: subfolder || 'root',
|
| 104 |
url: result.url,
|
|
|
|
| 68 |
|
| 69 |
const { repo_id, token, subfolder } = req.body;
|
| 70 |
|
| 71 |
+
// Gunakan env variable jika tidak dikirim via request
|
| 72 |
+
const finalRepoId = repo_id || process.env.HF_REPO_ID;
|
| 73 |
+
const finalToken = token || process.env.HF_TOKEN;
|
| 74 |
+
|
| 75 |
// Validasi required fields
|
| 76 |
+
if (!finalRepoId || !finalToken) {
|
| 77 |
// Hapus file yang sudah di-upload
|
| 78 |
fs.unlinkSync(req.file.path);
|
| 79 |
|
| 80 |
return res.status(400).json({
|
| 81 |
success: false,
|
| 82 |
+
error: 'repo_id dan token diperlukan (kirim via request atau set di .env)',
|
| 83 |
+
required_fields: ['repo_id', 'token'],
|
| 84 |
+
hint: 'Set HF_REPO_ID dan HF_TOKEN di .env atau kirim via form data'
|
| 85 |
});
|
| 86 |
}
|
| 87 |
|
|
|
|
| 89 |
const result = await hfUploader.uploadFile({
|
| 90 |
filePath: req.file.path,
|
| 91 |
fileName: req.file.originalname,
|
| 92 |
+
repoId: finalRepoId,
|
| 93 |
+
token: finalToken,
|
| 94 |
subfolder: subfolder || ''
|
| 95 |
});
|
| 96 |
|
|
|
|
| 103 |
data: {
|
| 104 |
file_name: req.file.originalname,
|
| 105 |
file_size: req.file.size,
|
| 106 |
+
repo_id: finalRepoId,
|
| 107 |
path_prefix: '/u/',
|
| 108 |
subfolder: subfolder || 'root',
|
| 109 |
url: result.url,
|