Spaces:
Sleeping
Sleeping
Update main.py
Browse files
main.py
CHANGED
|
@@ -1,11 +1,40 @@
|
|
| 1 |
-
from fastapi import FastAPI, UploadFile, File, HTTPException
|
|
|
|
| 2 |
from fastapi.responses import FileResponse
|
| 3 |
from typing import List, Dict
|
| 4 |
import os
|
| 5 |
import shutil
|
| 6 |
import uuid
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
# Create uploads directory if it doesn't exist
|
| 11 |
UPLOAD_DIR = "uploads"
|
|
@@ -17,6 +46,37 @@ file_codes: Dict[str, dict] = {}
|
|
| 17 |
# Reverse mapping: {filename: {"code": code, "user_id": user_id}}
|
| 18 |
filename_codes: Dict[str, dict] = {}
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
@app.post("/upload/")
|
| 21 |
async def upload_file(file: UploadFile = File(...), user_id: str = None):
|
| 22 |
try:
|
|
@@ -32,6 +92,10 @@ async def upload_file(file: UploadFile = File(...), user_id: str = None):
|
|
| 32 |
file_codes[unique_code] = {"filename": file.filename, "user_id": user_id}
|
| 33 |
filename_codes[file.filename] = {"code": unique_code, "user_id": user_id}
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
return {
|
| 36 |
"filename": file.filename,
|
| 37 |
"access_code": unique_code,
|
|
@@ -144,6 +208,23 @@ async def direct_download(access_code: str):
|
|
| 144 |
except Exception as e:
|
| 145 |
raise HTTPException(status_code=500, detail=str(e))
|
| 146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
if __name__ == "__main__":
|
| 148 |
import uvicorn
|
| 149 |
uvicorn.run(app, host="0.0.0.0", port=7860)
|
|
|
|
| 1 |
+
from fastapi import FastAPI, UploadFile, File, HTTPException, Depends, status
|
| 2 |
+
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
| 3 |
from fastapi.responses import FileResponse
|
| 4 |
from typing import List, Dict
|
| 5 |
import os
|
| 6 |
import shutil
|
| 7 |
import uuid
|
| 8 |
+
from collections import defaultdict
|
| 9 |
+
import secrets
|
| 10 |
+
from config import DOCS_USERNAME, DOCS_PASSWORD
|
| 11 |
|
| 12 |
+
# Initialize security
|
| 13 |
+
security = HTTPBasic()
|
| 14 |
+
|
| 15 |
+
def verify_credentials(credentials: HTTPBasicCredentials = Depends(security)):
|
| 16 |
+
"""Verify HTTP Basic Auth credentials"""
|
| 17 |
+
is_username_correct = secrets.compare_digest(credentials.username, DOCS_USERNAME)
|
| 18 |
+
is_password_correct = secrets.compare_digest(credentials.password, DOCS_PASSWORD)
|
| 19 |
+
|
| 20 |
+
if not (is_username_correct and is_password_correct):
|
| 21 |
+
raise HTTPException(
|
| 22 |
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
| 23 |
+
detail="Invalid credentials",
|
| 24 |
+
headers={"WWW-Authenticate": "Basic"},
|
| 25 |
+
)
|
| 26 |
+
return credentials
|
| 27 |
+
|
| 28 |
+
# Initialize FastAPI with auth for docs
|
| 29 |
+
app = FastAPI(
|
| 30 |
+
title="File Sharing API",
|
| 31 |
+
description="API for file sharing service",
|
| 32 |
+
version="1.0.0",
|
| 33 |
+
docs_url="/docs",
|
| 34 |
+
redoc_url="/redoc",
|
| 35 |
+
dependencies=[Depends(verify_credentials)],
|
| 36 |
+
openapi_url="/openapi.json"
|
| 37 |
+
)
|
| 38 |
|
| 39 |
# Create uploads directory if it doesn't exist
|
| 40 |
UPLOAD_DIR = "uploads"
|
|
|
|
| 46 |
# Reverse mapping: {filename: {"code": code, "user_id": user_id}}
|
| 47 |
filename_codes: Dict[str, dict] = {}
|
| 48 |
|
| 49 |
+
# Add this class after other class definitions
|
| 50 |
+
class UserStats:
|
| 51 |
+
def __init__(self):
|
| 52 |
+
self.upload_counts = defaultdict(int)
|
| 53 |
+
self.download_counts = defaultdict(int)
|
| 54 |
+
self.total_bytes_uploaded = defaultdict(int)
|
| 55 |
+
self.total_bytes_downloaded = defaultdict(int)
|
| 56 |
+
self.last_activity = defaultdict(str)
|
| 57 |
+
|
| 58 |
+
def log_upload(self, user_id: str, file_size: int, filename: str):
|
| 59 |
+
self.upload_counts[user_id] += 1
|
| 60 |
+
self.total_bytes_uploaded[user_id] += file_size
|
| 61 |
+
self.last_activity[user_id] = f"Uploaded: {filename}"
|
| 62 |
+
|
| 63 |
+
def log_download(self, user_id: str, file_size: int, filename: str):
|
| 64 |
+
self.download_counts[user_id] += 1
|
| 65 |
+
self.total_bytes_downloaded[user_id] += file_size
|
| 66 |
+
self.last_activity[user_id] = f"Downloaded: {filename}"
|
| 67 |
+
|
| 68 |
+
def get_user_stats(self, user_id: str) -> dict:
|
| 69 |
+
return {
|
| 70 |
+
"uploads": self.upload_counts[user_id],
|
| 71 |
+
"downloads": self.download_counts[user_id],
|
| 72 |
+
"bytes_uploaded": self.total_bytes_uploaded[user_id],
|
| 73 |
+
"bytes_downloaded": self.total_bytes_downloaded[user_id],
|
| 74 |
+
"last_activity": self.last_activity.get(user_id, "No activity")
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
# Initialize stats
|
| 78 |
+
user_stats = UserStats()
|
| 79 |
+
|
| 80 |
@app.post("/upload/")
|
| 81 |
async def upload_file(file: UploadFile = File(...), user_id: str = None):
|
| 82 |
try:
|
|
|
|
| 92 |
file_codes[unique_code] = {"filename": file.filename, "user_id": user_id}
|
| 93 |
filename_codes[file.filename] = {"code": unique_code, "user_id": user_id}
|
| 94 |
|
| 95 |
+
# Log the upload
|
| 96 |
+
file_size = os.path.getsize(file_path)
|
| 97 |
+
user_stats.log_upload(user_id, file_size, file.filename)
|
| 98 |
+
|
| 99 |
return {
|
| 100 |
"filename": file.filename,
|
| 101 |
"access_code": unique_code,
|
|
|
|
| 208 |
except Exception as e:
|
| 209 |
raise HTTPException(status_code=500, detail=str(e))
|
| 210 |
|
| 211 |
+
# Add new endpoint for stats
|
| 212 |
+
@app.get("/stats/{user_id}")
|
| 213 |
+
async def get_user_stats(user_id: str):
|
| 214 |
+
try:
|
| 215 |
+
stats = user_stats.get_user_stats(user_id)
|
| 216 |
+
return stats
|
| 217 |
+
except Exception as e:
|
| 218 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 219 |
+
|
| 220 |
+
@app.post("/log_download")
|
| 221 |
+
async def log_download(user_id: str, file_size: int, filename: str):
|
| 222 |
+
try:
|
| 223 |
+
user_stats.log_download(user_id, file_size, filename)
|
| 224 |
+
return {"message": "Download logged successfully"}
|
| 225 |
+
except Exception as e:
|
| 226 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 227 |
+
|
| 228 |
if __name__ == "__main__":
|
| 229 |
import uvicorn
|
| 230 |
uvicorn.run(app, host="0.0.0.0", port=7860)
|