dpv007 commited on
Commit
758cb51
·
1 Parent(s): 84379ba
Files changed (2) hide show
  1. .gitignore +15 -0
  2. keystone-backend/main.py +27 -17
.gitignore ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Environments
2
+ .env
3
+ venv/
4
+ __pycache__/
5
+
6
+ # Local Storage (prevents uploading test photos to git)
7
+ data/
8
+
9
+ # Node
10
+ node_modules/
11
+ .expo/
12
+
13
+ # OS Files
14
+ .DS_Store
15
+ Thumbs.db
keystone-backend/main.py CHANGED
@@ -1,28 +1,35 @@
1
  import os
2
- import shutil
3
  from fastapi import FastAPI, HTTPException, Header, Depends, UploadFile, File
4
  from fastapi.middleware.cors import CORSMiddleware
5
  from pydantic import BaseModel
6
  from dotenv import load_dotenv
7
 
8
- # Load environment variables
9
  load_dotenv()
10
 
11
  app = FastAPI(title="KeyStone API", version="0.1.0")
12
 
13
- # Fetch credentials
14
  DEV_USERNAME = os.getenv("DEV_USERNAME", "admin")
15
  DEV_PASSWORD = os.getenv("DEV_LOGIN_PASSWORD", "password123")
16
  MOCK_TOKEN = "mock-jwt-token-xyz123"
17
 
18
- # --- PERSISTENT STORAGE SETUP ---
19
- # If running in HF Spaces with persistent storage, it mounts to /data.
20
- # Locally, we will default to creating a folder called "data/photos" in the project root.
21
- BASE_STORAGE_DIR = os.getenv("STORAGE_DIR", "./data/photos")
 
 
 
22
 
23
- # Ensure the directory exists when the server starts
24
- os.makedirs(BASE_STORAGE_DIR, exist_ok=True)
25
- # --------------------------------
 
 
 
 
 
26
 
27
  app.add_middleware(
28
  CORSMiddleware,
@@ -47,7 +54,11 @@ def verify_mock_token(authorization: str = Header(None)):
47
 
48
  @app.get("/health")
49
  async def health_check():
50
- return {"status": "ok", "service": "KeyStone API", "storage_path": BASE_STORAGE_DIR}
 
 
 
 
51
 
52
  @app.post("/auth/login")
53
  async def mock_login(payload: LoginPayload):
@@ -59,22 +70,21 @@ async def mock_login(payload: LoginPayload):
59
  }
60
  raise HTTPException(status_code=400, detail="Incorrect username or password")
61
 
62
- # --- NEW UPLOAD ENDPOINT ---
63
  @app.post("/upload")
64
  async def upload_photo(file: UploadFile = File(...), token: str = Depends(verify_mock_token)):
65
- # Create the full file path safely
66
- file_path = os.path.join(BASE_STORAGE_DIR, file.filename)
67
 
68
  try:
69
- # Save the file in chunks to keep memory usage low
70
  with open(file_path, "wb") as buffer:
71
- while content := await file.read(1024 * 1024): # Read in 1MB chunks
72
  buffer.write(content)
73
  except Exception as e:
74
  raise HTTPException(status_code=500, detail=f"Could not save file: {str(e)}")
75
 
76
  return {
77
- "message": "Photo uploaded successfully!",
78
  "filename": file.filename,
79
  "path": file_path
80
  }
 
1
  import os
 
2
  from fastapi import FastAPI, HTTPException, Header, Depends, UploadFile, File
3
  from fastapi.middleware.cors import CORSMiddleware
4
  from pydantic import BaseModel
5
  from dotenv import load_dotenv
6
 
7
+ # Load local environment variables
8
  load_dotenv()
9
 
10
  app = FastAPI(title="KeyStone API", version="0.1.0")
11
 
12
+ # Fetch credentials from environment variables
13
  DEV_USERNAME = os.getenv("DEV_USERNAME", "admin")
14
  DEV_PASSWORD = os.getenv("DEV_LOGIN_PASSWORD", "password123")
15
  MOCK_TOKEN = "mock-jwt-token-xyz123"
16
 
17
+ # --- SMART BUCKET STORAGE SETUP ---
18
+ # If the root "/data" folder exists, Hugging Face mounted the bucket.
19
+ if os.path.exists("/data"):
20
+ BASE_STORAGE_DIR = "/data"
21
+ else:
22
+ # Otherwise, fall back to a local folder for Windows testing.
23
+ BASE_STORAGE_DIR = os.getenv("STORAGE_DIR", "./data")
24
 
25
+ # Define your specific bucket paths
26
+ ORIGINALS_DIR = os.path.join(BASE_STORAGE_DIR, "originals")
27
+ THUMBNAILS_DIR = os.path.join(BASE_STORAGE_DIR, "thumbnails")
28
+
29
+ # Ensure these directories exist when the server starts
30
+ os.makedirs(ORIGINALS_DIR, exist_ok=True)
31
+ os.makedirs(THUMBNAILS_DIR, exist_ok=True)
32
+ # ----------------------------------
33
 
34
  app.add_middleware(
35
  CORSMiddleware,
 
54
 
55
  @app.get("/health")
56
  async def health_check():
57
+ return {
58
+ "status": "ok",
59
+ "service": "KeyStone API",
60
+ "storage_path": BASE_STORAGE_DIR
61
+ }
62
 
63
  @app.post("/auth/login")
64
  async def mock_login(payload: LoginPayload):
 
70
  }
71
  raise HTTPException(status_code=400, detail="Incorrect username or password")
72
 
 
73
  @app.post("/upload")
74
  async def upload_photo(file: UploadFile = File(...), token: str = Depends(verify_mock_token)):
75
+ # Save directly to the originals folder
76
+ file_path = os.path.join(ORIGINALS_DIR, file.filename)
77
 
78
  try:
79
+ # Save in 1MB chunks to prevent memory spikes
80
  with open(file_path, "wb") as buffer:
81
+ while content := await file.read(1024 * 1024):
82
  buffer.write(content)
83
  except Exception as e:
84
  raise HTTPException(status_code=500, detail=f"Could not save file: {str(e)}")
85
 
86
  return {
87
+ "message": "Photo securely uploaded!",
88
  "filename": file.filename,
89
  "path": file_path
90
  }