LogicGoInfotechSpaces commited on
Commit
a0088ec
·
1 Parent(s): c85fec3

Update Firebase initialization to auto-detect credentials file and add setup guide

Browse files
Files changed (2) hide show
  1. FIREBASE_SETUP.md +156 -0
  2. app/main_sdxl.py +121 -28
FIREBASE_SETUP.md ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Firebase Setup Guide
2
+
3
+ ## Firebase Project Information
4
+
5
+ **Project ID:** `colorize-662df`
6
+ **Credentials File:** `colorize-662df-firebase-adminsdk-fbsvc-bfd21c77c6.json`
7
+
8
+ ## Required Firebase Configuration
9
+
10
+ ### 1. Firebase Admin SDK Credentials ✅
11
+ The credentials file is already in the project:
12
+ - File: `colorize-662df-firebase-adminsdk-fbsvc-bfd21c77c6.json`
13
+ - The application will automatically detect and use this file
14
+
15
+ ### 2. Firebase Web API Key (Required for Login/Register)
16
+
17
+ To get your Firebase Web API Key:
18
+
19
+ 1. Go to [Firebase Console](https://console.firebase.google.com/)
20
+ 2. Select your project: **colorize-662df**
21
+ 3. Click the gear icon ⚙️ → **Project settings**
22
+ 4. Scroll down to **Your apps** section
23
+ 5. Find the **Web API Key** (starts with `AIza...`)
24
+ 6. Copy this key
25
+
26
+ **Set it as environment variable:**
27
+ ```bash
28
+ export FIREBASE_API_KEY="AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68"
29
+ ```
30
+
31
+ Or in Hugging Face Spaces:
32
+ - Go to Settings → Secrets
33
+ - Add secret: `FIREBASE_API_KEY` = `AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68`
34
+
35
+ ### 3. Firebase App Check Configuration
36
+
37
+ For App Check to work, you need:
38
+
39
+ 1. **Enable App Check in Firebase Console:**
40
+ - Go to Firebase Console → **App Check**
41
+ - Register your app
42
+ - Choose **reCAPTCHA Enterprise** provider
43
+ - Get your **reCAPTCHA Site Key**
44
+
45
+ 2. **Frontend Setup:**
46
+ ```javascript
47
+ import { initializeApp } from "firebase/app";
48
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider, getToken } from "firebase/app-check";
49
+
50
+ const firebaseConfig = {
51
+ apiKey: "AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68",
52
+ authDomain: "colorize-662df.firebaseapp.com",
53
+ projectId: "colorize-662df",
54
+ storageBucket: "colorize-662df.firebasestorage.app",
55
+ messagingSenderId: "69166278311",
56
+ appId: "1:69166278311:web:0e8c50b8dd8627aaeadd82",
57
+ measurementId: "G-58CC2J8XKX"
58
+ };
59
+
60
+ const app = initializeApp(firebaseConfig);
61
+
62
+ const appCheck = initializeAppCheck(app, {
63
+ provider: new ReCaptchaEnterpriseProvider('YOUR_RECAPTCHA_SITE_KEY'),
64
+ isTokenAutoRefreshEnabled: true
65
+ });
66
+
67
+ // Get token for API requests
68
+ const token = await getToken(appCheck);
69
+ ```
70
+
71
+ ## Environment Variables
72
+
73
+ ### For Local Development:
74
+ ```bash
75
+ # Firebase credentials (optional if file is in project root)
76
+ export FIREBASE_CREDENTIALS_PATH="./colorize-662df-firebase-adminsdk-fbsvc-bfd21c77c6.json"
77
+
78
+ # Firebase Web API Key (required for /auth/login and /auth/register)
79
+ export FIREBASE_API_KEY="AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68"
80
+
81
+ # Optional: Disable auth for testing
82
+ export DISABLE_AUTH="false"
83
+
84
+ # Optional: Disable App Check
85
+ export ENABLE_APP_CHECK="true"
86
+ ```
87
+
88
+ ### For Hugging Face Spaces:
89
+ Add these as **Secrets** in Space Settings:
90
+
91
+ 1. **FIREBASE_CREDENTIALS** - Paste the entire contents of `colorize-662df-firebase-adminsdk-fbsvc-bfd21c77c6.json`
92
+ 2. **FIREBASE_API_KEY** - Your Web API Key (`AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68`)
93
+ 3. **HF_TOKEN** - Your Hugging Face token (for Inference API)
94
+
95
+ ## Testing Firebase Connection
96
+
97
+ ### Test 1: Health Check (No Auth Required)
98
+ ```bash
99
+ curl https://logicgoinfotechspaces-text-guided-image-colorization.hf.space/health
100
+ ```
101
+
102
+ ### Test 2: Register User (Requires FIREBASE_API_KEY)
103
+ ```bash
104
+ curl -X POST https://logicgoinfotechspaces-text-guided-image-colorization.hf.space/auth/register \
105
+ -H "Content-Type: application/json" \
106
+ -d '{
107
+ "email": "test@example.com",
108
+ "password": "password123",
109
+ "display_name": "Test User"
110
+ }'
111
+ ```
112
+
113
+ ### Test 3: Login (Requires FIREBASE_API_KEY)
114
+ ```bash
115
+ curl -X POST https://logicgoinfotechspaces-text-guided-image-colorization.hf.space/auth/login \
116
+ -H "Content-Type: application/json" \
117
+ -d '{
118
+ "email": "test@example.com",
119
+ "password": "password123"
120
+ }'
121
+ ```
122
+
123
+ ### Test 4: Colorize with App Check Token
124
+ ```bash
125
+ curl -X POST https://logicgoinfotechspaces-text-guided-image-colorization.hf.space/colorize \
126
+ -H "X-Firebase-AppCheck: YOUR_APP_CHECK_TOKEN" \
127
+ -F "file=@image.jpg"
128
+ ```
129
+
130
+ ## Troubleshooting
131
+
132
+ ### Issue: "Firebase not initialized"
133
+ **Solution:** Make sure the credentials file exists and is readable
134
+
135
+ ### Issue: "Firebase API key not configured" (for login/register)
136
+ **Solution:** Set `FIREBASE_API_KEY` environment variable
137
+
138
+ ### Issue: "Invalid App Check token"
139
+ **Solution:**
140
+ 1. Make sure App Check is enabled in Firebase Console
141
+ 2. Verify you're sending the token in `X-Firebase-AppCheck` header
142
+ 3. Check that reCAPTCHA Enterprise is properly configured
143
+
144
+ ### Issue: "Missing App Check token"
145
+ **Solution:**
146
+ - Either provide `X-Firebase-AppCheck` header
147
+ - Or set `ENABLE_APP_CHECK=false` to disable (not recommended for production)
148
+
149
+ ## Current Firebase Config
150
+
151
+ Based on your credentials file:
152
+ - **Project ID:** `colorize-662df`
153
+ - **Service Account:** `firebase-adminsdk-fbsvc@colorize-662df.iam.gserviceaccount.com`
154
+ - **Auth Domain:** `colorize-662df.firebaseapp.com`
155
+ - **Storage Bucket:** `colorize-662df.firebasestorage.app`
156
+
app/main_sdxl.py CHANGED
@@ -56,19 +56,46 @@ app.add_middleware(
56
  )
57
 
58
  # Initialize Firebase Admin SDK
59
- firebase_cred_path = os.getenv("FIREBASE_CREDENTIALS_PATH", "/tmp/firebase-adminsdk.json")
60
- if os.path.exists(firebase_cred_path):
61
- try:
62
- cred = credentials.Certificate(firebase_cred_path)
63
- firebase_admin.initialize_app(cred)
64
- logger.info("Firebase Admin SDK initialized")
65
- except Exception as e:
66
- logger.warning("Failed to initialize Firebase: %s", str(e))
 
 
 
 
 
 
 
67
  try:
68
- firebase_admin.initialize_app()
69
- except:
70
- pass
71
- else:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  logger.warning("Firebase credentials file not found. App Check will be disabled.")
73
  try:
74
  firebase_admin.initialize_app()
@@ -220,10 +247,29 @@ def _extract_bearer_token(authorization_header: str | None) -> str | None:
220
 
221
 
222
  async def verify_request(request: Request):
223
- """Verify Firebase authentication"""
 
 
 
 
 
224
  if not firebase_admin._apps or os.getenv("DISABLE_AUTH", "false").lower() == "true":
225
  return True
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  bearer = _extract_bearer_token(request.headers.get("Authorization"))
228
  if bearer:
229
  try:
@@ -234,18 +280,13 @@ async def verify_request(request: Request):
234
  except Exception as e:
235
  logger.warning("Auth token verification failed: %s", str(e))
236
 
 
237
  if settings.ENABLE_APP_CHECK:
238
- app_check_token = request.headers.get("X-Firebase-AppCheck")
239
  if not app_check_token:
240
  raise HTTPException(status_code=401, detail="Missing App Check token")
241
- try:
242
- app_check_claims = app_check.verify_token(app_check_token)
243
- logger.info("App Check token verified for: %s", app_check_claims.get("app_id"))
244
- return True
245
- except Exception as e:
246
- logger.warning("App Check token verification failed: %s", str(e))
247
- raise HTTPException(status_code=401, detail="Invalid App Check token")
248
 
 
249
  return True
250
 
251
 
@@ -447,15 +488,17 @@ async def api_info():
447
  "version": "1.0.0",
448
  "endpoints": {
449
  "health": "/health",
 
 
 
 
 
450
  "auth": {
451
  "register": "/auth/register",
452
  "login": "/auth/login",
453
  "me": "/auth/me",
454
  "refresh": "/auth/refresh"
455
  },
456
- "colorize": "/colorize",
457
- "download": "/download/{file_id}",
458
- "results": "/results/{filename}",
459
  "gradio": "/"
460
  }
461
  }
@@ -543,6 +586,48 @@ def colorize_image_sdxl(
543
  raise RuntimeError(f"Failed to colorize image: {str(e)}")
544
 
545
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
546
  @app.post("/colorize")
547
  async def colorize_api(
548
  file: UploadFile = File(...),
@@ -581,12 +666,20 @@ async def colorize_api(
581
 
582
  logger.info("Colorized image saved: %s", output_filename)
583
 
 
 
 
 
 
 
 
584
  return JSONResponse({
585
  "success": True,
586
- "result_id": output_filename.replace(".png", ""),
587
- "caption": caption,
588
- "download_url": f"/results/{output_filename}",
589
- "api_download": f"/download/{output_filename.replace('.png', '')}"
 
590
  })
591
  except Exception as e:
592
  logger.error("Error colorizing image: %s", str(e))
 
56
  )
57
 
58
  # Initialize Firebase Admin SDK
59
+ # Try multiple possible paths for Firebase credentials
60
+ firebase_cred_paths = [
61
+ os.getenv("FIREBASE_CREDENTIALS_PATH"),
62
+ "/tmp/firebase-adminsdk.json",
63
+ "/data/firebase-adminsdk.json",
64
+ "colorize-662df-firebase-adminsdk-fbsvc-bfd21c77c6.json",
65
+ os.path.join(os.path.dirname(__file__), "..", "colorize-662df-firebase-adminsdk-fbsvc-bfd21c77c6.json"),
66
+ ]
67
+
68
+ firebase_initialized = False
69
+ for cred_path in firebase_cred_paths:
70
+ if not cred_path:
71
+ continue
72
+ cred_path = os.path.abspath(cred_path)
73
+ if os.path.exists(cred_path):
74
  try:
75
+ cred = credentials.Certificate(cred_path)
76
+ firebase_admin.initialize_app(cred)
77
+ logger.info("Firebase Admin SDK initialized from: %s", cred_path)
78
+ firebase_initialized = True
79
+ break
80
+ except Exception as e:
81
+ logger.warning("Failed to initialize Firebase from %s: %s", cred_path, str(e))
82
+ continue
83
+
84
+ # Also try loading from environment variable (for Hugging Face Spaces)
85
+ if not firebase_initialized:
86
+ firebase_json = os.getenv("FIREBASE_CREDENTIALS")
87
+ if firebase_json:
88
+ try:
89
+ import json
90
+ firebase_dict = json.loads(firebase_json)
91
+ cred = credentials.Certificate(firebase_dict)
92
+ firebase_admin.initialize_app(cred)
93
+ logger.info("Firebase Admin SDK initialized from environment variable")
94
+ firebase_initialized = True
95
+ except Exception as e:
96
+ logger.warning("Failed to initialize Firebase from environment: %s", str(e))
97
+
98
+ if not firebase_initialized:
99
  logger.warning("Firebase credentials file not found. App Check will be disabled.")
100
  try:
101
  firebase_admin.initialize_app()
 
247
 
248
 
249
  async def verify_request(request: Request):
250
+ """
251
+ Verify Firebase authentication.
252
+ Priority:
253
+ 1. Firebase App Check token (X-Firebase-AppCheck header) - Primary method per documentation
254
+ 2. Firebase Auth ID token (Authorization: Bearer header) - Fallback for auth endpoints
255
+ """
256
  if not firebase_admin._apps or os.getenv("DISABLE_AUTH", "false").lower() == "true":
257
  return True
258
 
259
+ # Primary: Check Firebase App Check token (X-Firebase-AppCheck header)
260
+ app_check_token = request.headers.get("X-Firebase-AppCheck")
261
+ if app_check_token:
262
+ try:
263
+ app_check_claims = app_check.verify_token(app_check_token)
264
+ logger.info("App Check token verified for: %s", app_check_claims.get("app_id"))
265
+ return True
266
+ except Exception as e:
267
+ logger.warning("App Check token verification failed: %s", str(e))
268
+ if settings.ENABLE_APP_CHECK:
269
+ raise HTTPException(status_code=401, detail="Invalid App Check token")
270
+
271
+ # Secondary: Check Firebase Auth ID token (Authorization: Bearer header)
272
+ # This is for /auth/* endpoints that use email/password login
273
  bearer = _extract_bearer_token(request.headers.get("Authorization"))
274
  if bearer:
275
  try:
 
280
  except Exception as e:
281
  logger.warning("Auth token verification failed: %s", str(e))
282
 
283
+ # If App Check is enabled and no valid token provided, require it
284
  if settings.ENABLE_APP_CHECK:
 
285
  if not app_check_token:
286
  raise HTTPException(status_code=401, detail="Missing App Check token")
287
+ raise HTTPException(status_code=401, detail="Invalid App Check token")
 
 
 
 
 
 
288
 
289
+ # If auth is disabled, allow access
290
  return True
291
 
292
 
 
488
  "version": "1.0.0",
489
  "endpoints": {
490
  "health": "/health",
491
+ "upload": "/upload",
492
+ "colorize": "/colorize",
493
+ "download": "/download/{file_id}",
494
+ "results": "/results/{filename}",
495
+ "uploads": "/uploads/{filename}",
496
  "auth": {
497
  "register": "/auth/register",
498
  "login": "/auth/login",
499
  "me": "/auth/me",
500
  "refresh": "/auth/refresh"
501
  },
 
 
 
502
  "gradio": "/"
503
  }
504
  }
 
586
  raise RuntimeError(f"Failed to colorize image: {str(e)}")
587
 
588
 
589
+ @app.post("/upload")
590
+ async def upload_image(
591
+ file: UploadFile = File(...),
592
+ verified: bool = Depends(verify_request)
593
+ ):
594
+ """
595
+ Upload an image and get the uploaded image URL.
596
+ Requires Firebase App Check authentication.
597
+ """
598
+ if not file.content_type or not file.content_type.startswith("image/"):
599
+ raise HTTPException(status_code=400, detail="File must be an image")
600
+
601
+ try:
602
+ # Generate unique filename
603
+ file_extension = file.filename.split('.')[-1] if file.filename else 'jpg'
604
+ image_id = f"{uuid.uuid4()}.{file_extension}"
605
+ file_path = UPLOAD_DIR / image_id
606
+
607
+ # Save uploaded file
608
+ img_bytes = await file.read()
609
+ with open(file_path, "wb") as f:
610
+ f.write(img_bytes)
611
+
612
+ logger.info("Image uploaded: %s", image_id)
613
+
614
+ # Get base URL from settings or environment
615
+ base_url = os.getenv("BASE_URL", settings.BASE_URL)
616
+ if not base_url or base_url == "http://localhost:8000":
617
+ # Try to get from request
618
+ base_url = "https://logicgoinfotechspaces-text-guided-image-colorization.hf.space"
619
+
620
+ return JSONResponse({
621
+ "success": True,
622
+ "image_id": image_id.replace(f".{file_extension}", ""),
623
+ "image_url": f"{base_url}/uploads/{image_id}",
624
+ "filename": image_id
625
+ })
626
+ except Exception as e:
627
+ logger.error("Error uploading image: %s", str(e))
628
+ raise HTTPException(status_code=500, detail=f"Error uploading image: {str(e)}")
629
+
630
+
631
  @app.post("/colorize")
632
  async def colorize_api(
633
  file: UploadFile = File(...),
 
666
 
667
  logger.info("Colorized image saved: %s", output_filename)
668
 
669
+ # Get base URL from settings or environment
670
+ base_url = os.getenv("BASE_URL", settings.BASE_URL)
671
+ if not base_url or base_url == "http://localhost:8000":
672
+ base_url = "https://logicgoinfotechspaces-text-guided-image-colorization.hf.space"
673
+
674
+ result_id = output_filename.replace(".png", "")
675
+
676
  return JSONResponse({
677
  "success": True,
678
+ "result_id": result_id,
679
+ "download_url": f"{base_url}/results/{output_filename}",
680
+ "api_download_url": f"{base_url}/download/{result_id}",
681
+ "filename": output_filename,
682
+ "caption": caption
683
  })
684
  except Exception as e:
685
  logger.error("Error colorizing image: %s", str(e))