ChandimaPrabath commited on
Commit
a8f0097
·
1 Parent(s): d01aa07
Files changed (6) hide show
  1. .gitignore +2 -0
  2. Dockerfile +16 -0
  3. app.py +93 -0
  4. index.html +58 -0
  5. requirements.txt +4 -0
  6. uploader.py +34 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ #.env
2
+ .env
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.9
5
+
6
+ RUN useradd -m -u 1000 user
7
+ USER user
8
+ ENV PATH="/home/user/.local/bin:$PATH"
9
+
10
+ WORKDIR /app
11
+
12
+ COPY --chown=user ./requirements.txt requirements.txt
13
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
14
+
15
+ COPY --chown=user . /app
16
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile, Form, BackgroundTasks, HTTPException
2
+ from fastapi.responses import HTMLResponse, JSONResponse
3
+ from pathlib import Path
4
+ from typing import List
5
+ from uploader import HuggingFaceUploader
6
+ import shutil
7
+ import uuid
8
+ import os
9
+
10
+ app = FastAPI()
11
+
12
+ # Initialize HuggingFaceUploader with your token and repo_id
13
+ hf_token = os.getenv("HF_TOKEN")
14
+ repo_id = os.getenv("REPO_ID")
15
+ uploader = HuggingFaceUploader(hf_token, repo_id)
16
+
17
+ # Directories for temporary uploads and status tracking
18
+ UPLOAD_FOLDER = Path("temp_uploads")
19
+ STATUS_FOLDER = Path("status")
20
+ UPLOAD_FOLDER.mkdir(exist_ok=True)
21
+ STATUS_FOLDER.mkdir(exist_ok=True)
22
+
23
+ def save_progress(status_file, filename, status):
24
+ """Helper function to update progress to a status file."""
25
+ with status_file.open("a", encoding="utf-8") as f:
26
+ f.write(f"{filename}: {status}\n")
27
+
28
+ def upload_file_task(temp_folder_path: Path, destination_folder: str, status_file: Path):
29
+ """Background task to upload files and log progress."""
30
+ try:
31
+ total_files = len(list(temp_folder_path.rglob('*')))
32
+ uploaded_files = 0
33
+
34
+ for local_path in temp_folder_path.rglob('*'):
35
+ if local_path.is_file():
36
+ relative_path = local_path.relative_to(temp_folder_path)
37
+ path_in_repo = str(Path(destination_folder) / relative_path).replace("\\", "/")
38
+
39
+ uploader.api.upload_file(
40
+ path_or_fileobj=str(local_path),
41
+ path_in_repo=path_in_repo,
42
+ repo_id=uploader.repo_id,
43
+ repo_type="model"
44
+ )
45
+
46
+ uploaded_files += 1
47
+ save_progress(status_file, str(local_path.name), "Uploaded")
48
+ # Log current progress
49
+ save_progress(status_file, "Progress", f"{uploaded_files}/{total_files} files uploaded.")
50
+
51
+ except Exception as e:
52
+ save_progress(status_file, "error", str(e))
53
+ finally:
54
+ # Clean up files
55
+ for file in temp_folder_path.glob('*'):
56
+ file.unlink()
57
+ temp_folder_path.rmdir()
58
+
59
+ @app.get("/", response_class=HTMLResponse)
60
+ async def main():
61
+ with open("index.html") as f:
62
+ return HTMLResponse(content=f.read())
63
+
64
+ @app.post("/upload")
65
+ async def upload_files(
66
+ background_tasks: BackgroundTasks,
67
+ destination_folder: str = Form(...),
68
+ files: List[UploadFile] = File(...)
69
+ ):
70
+ temp_folder_path = UPLOAD_FOLDER / uuid.uuid4().hex
71
+ temp_folder_path.mkdir(parents=True, exist_ok=True)
72
+
73
+ # Save uploaded files temporarily
74
+ for file in files:
75
+ file_path = temp_folder_path / file.filename
76
+ with file_path.open("wb") as buffer:
77
+ shutil.copyfileobj(file.file, buffer)
78
+
79
+ # Create a status file for tracking progress
80
+ status_file = STATUS_FOLDER / f"{temp_folder_path.name}.txt"
81
+ background_tasks.add_task(upload_file_task, temp_folder_path, destination_folder, status_file)
82
+ return JSONResponse(content={"status_id": temp_folder_path.name})
83
+
84
+ @app.get("/progress/{status_id}")
85
+ async def get_progress(status_id: str):
86
+ """Get the progress of the upload from the status file."""
87
+ status_file = STATUS_FOLDER / f"{status_id}.txt"
88
+ if not status_file.exists():
89
+ raise HTTPException(status_code=404, detail="Status not found")
90
+
91
+ with status_file.open("r", encoding="utf-8") as f:
92
+ progress = f.readlines()
93
+ return JSONResponse(content={"progress": progress})
index.html ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>File Upload with Progress</title>
7
+ </head>
8
+ <body>
9
+ <h2>Upload Files to Hugging Face Repository</h2>
10
+ <form id="uploadForm" enctype="multipart/form-data">
11
+ <label for="destination_folder">Destination Folder:</label>
12
+ <input type="text" id="destination_folder" name="destination_folder" required>
13
+
14
+ <label for="files">Select Files:</label>
15
+ <input type="file" id="files" name="files" multiple required>
16
+
17
+ <button type="submit">Upload</button>
18
+ </form>
19
+
20
+ <div id="progress">
21
+ <h3>Upload Progress:</h3>
22
+ <pre id="progressText">No upload in progress...</pre>
23
+ </div>
24
+
25
+ <script>
26
+ document.getElementById("uploadForm").onsubmit = async function(event) {
27
+ event.preventDefault();
28
+ const formData = new FormData(this);
29
+
30
+ try {
31
+ const response = await fetch("/upload", {
32
+ method: "POST",
33
+ body: formData
34
+ });
35
+ const result = await response.json();
36
+ const statusId = result.status_id;
37
+
38
+ // Start polling for progress
39
+ const progressText = document.getElementById("progressText");
40
+ progressText.textContent = "Starting upload...";
41
+
42
+ const intervalId = setInterval(async () => {
43
+ const progressResponse = await fetch(`/progress/${statusId}`);
44
+ if (progressResponse.ok) {
45
+ const progressResult = await progressResponse.json();
46
+ progressText.textContent = progressResult.progress.join("");
47
+ } else {
48
+ clearInterval(intervalId);
49
+ progressText.textContent += "\nUpload completed or status not found.";
50
+ }
51
+ }, 2000);
52
+ } catch (error) {
53
+ document.getElementById("progressText").textContent = "Upload failed.";
54
+ }
55
+ };
56
+ </script>
57
+ </body>
58
+ </html>
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ fastapi
2
+ uvicorn[standard]
3
+ requests
4
+ aiofiles
uploader.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import HfApi
2
+ from pathlib import Path
3
+
4
+ class HuggingFaceUploader:
5
+ def __init__(self, hf_token: str, repo_id: str):
6
+ self.api = HfApi(token=hf_token)
7
+ self.repo_id = repo_id
8
+
9
+ def upload_folder_with_structure(self, folder_path: str, destination_folder: str):
10
+ folder_path = Path(folder_path)
11
+ destination_folder = Path(destination_folder)
12
+
13
+ for local_path in folder_path.rglob('*'):
14
+ if local_path.is_file():
15
+ # Define the path in the repository
16
+ relative_path = local_path.relative_to(folder_path)
17
+ path_in_repo = str(destination_folder / relative_path).replace("\\", "/") # Ensuring forward slashes
18
+
19
+ # Upload each file to the correct path in the repository
20
+ self.api.upload_file(
21
+ path_or_fileobj=str(local_path),
22
+ path_in_repo=path_in_repo,
23
+ repo_id=self.repo_id,
24
+ repo_type="model"
25
+ )
26
+ print(f"Uploaded '{local_path}' to '{path_in_repo}' in the Hugging Face repository '{self.repo_id}'.")
27
+
28
+ if __name__ == "__main__":
29
+ hf_token = ""
30
+ repo_id = ""
31
+ folder_path = "content" # Set the local folder path
32
+ destination_folder = "hindi" # Adjust the destination folder structure as needed
33
+ uploader = HuggingFaceUploader(hf_token, repo_id)
34
+ uploader.upload_folder_with_structure(folder_path, destination_folder)