feat: add /reset-password page
Browse files- README.md +95 -95
- app.py +3 -3
- bootstrap.py +17 -5
README.md
CHANGED
|
@@ -1,95 +1,95 @@
|
|
| 1 |
-
---
|
| 2 |
-
title:
|
| 3 |
-
emoji: ๐
|
| 4 |
-
colorFrom: blue
|
| 5 |
-
colorTo: green
|
| 6 |
-
sdk: docker
|
| 7 |
-
pinned: false
|
| 8 |
-
---
|
| 9 |
-
|
| 10 |
-
#
|
| 11 |
-
|
| 12 |
-
Public gateway with Supabase authentication that dynamically loads the private ver20 application from `DLPO/habadashi` Space.
|
| 13 |
-
|
| 14 |
-
## Features
|
| 15 |
-
|
| 16 |
-
- Supabase email/password authentication
|
| 17 |
-
- Cookie-based session management
|
| 18 |
-
- Dynamic loading of private application code (source code not exposed in public repo)
|
| 19 |
-
- Role-based access control via profiles table
|
| 20 |
-
|
| 21 |
-
## Environment Variables (Set in HF Space Secrets)
|
| 22 |
-
|
| 23 |
-
- `SUPABASE_URL`: Your Supabase project URL
|
| 24 |
-
- `SUPABASE_KEY`: Your Supabase anon/service key
|
| 25 |
-
- `HF_TOKEN`: Hugging Face token with access to private `DLPO/habadashi` Space
|
| 26 |
-
- `OPENAI_KEY`: OpenAI API key (required by ver20)
|
| 27 |
-
- `CLIENTPOOL`: Client pool configuration (required by ver20)
|
| 28 |
-
|
| 29 |
-
## Architecture
|
| 30 |
-
|
| 31 |
-
1. User visits public Space
|
| 32 |
-
2. Bootstrap downloads ver20 from private `DLPO/habadashi` Space
|
| 33 |
-
3. User logs in with Supabase credentials
|
| 34 |
-
4. On successful login, ver20 Gradio app is mounted at `/app/`
|
| 35 |
-
5. User profile and organization info loaded from `profiles` table
|
| 36 |
-
|
| 37 |
-
## Startup Phase Logging
|
| 38 |
-
|
| 39 |
-
The application logs structured startup phases to help diagnose issues. Look for these phase markers in the logs:
|
| 40 |
-
|
| 41 |
-
### Expected Startup Sequence
|
| 42 |
-
|
| 43 |
-
1. `[STARTUP_META]` - Environment and configuration info
|
| 44 |
-
2. `[PHASE] bootstrap_start` - Begin downloading private app
|
| 45 |
-
3. `[PHASE] bootstrap_end success=true` - Private app downloaded
|
| 46 |
-
4. `[PHASE] supabase_init_start` - Initialize Supabase client
|
| 47 |
-
5. `[PHASE] supabase_init_end success=true` - Supabase ready
|
| 48 |
-
6. `[PHASE] fastapi_init_start/end` - FastAPI app created
|
| 49 |
-
7. `[PHASE] create_ui_start/end` - Login UI created
|
| 50 |
-
8. `[PHASE] import_ver20_start` - Import ver20 app
|
| 51 |
-
9. `[PHASE] import_ver20_end success=true` - Ver20 loaded
|
| 52 |
-
10. `[PHASE] mount_login_start/end` - Login UI mounted
|
| 53 |
-
11. `[PHASE] mount_app_start/end` - Ver20 app mounted
|
| 54 |
-
12. `[STARTUP_COMPLETE]` - All phases complete
|
| 55 |
-
|
| 56 |
-
### Health Check Endpoint
|
| 57 |
-
|
| 58 |
-
Once started, check the health endpoint:
|
| 59 |
-
|
| 60 |
-
```bash
|
| 61 |
-
curl https://
|
| 62 |
-
```
|
| 63 |
-
|
| 64 |
-
Expected response:
|
| 65 |
-
```json
|
| 66 |
-
{
|
| 67 |
-
"ok": true,
|
| 68 |
-
"ver20_loaded": true,
|
| 69 |
-
"private_app_dir": "./private_app"
|
| 70 |
-
}
|
| 71 |
-
```
|
| 72 |
-
|
| 73 |
-
### Debugging Startup Failures
|
| 74 |
-
|
| 75 |
-
If the Space fails to start or restarts repeatedly:
|
| 76 |
-
|
| 77 |
-
1. **Check the last phase reached** in logs
|
| 78 |
-
2. **Look for `[ERROR]` and `[TRACEBACK]` markers** after the last phase
|
| 79 |
-
3. **Common failure points:**
|
| 80 |
-
- `bootstrap_end success=false` - HF_TOKEN missing or invalid
|
| 81 |
-
- `supabase_init_end success=false` - SUPABASE_URL/KEY missing
|
| 82 |
-
- `import_ver20_end success=false` - Ver20 app.py structure issue
|
| 83 |
-
- No phases after `mount_app_end` - Port binding or health check issue
|
| 84 |
-
|
| 85 |
-
### Request Logging
|
| 86 |
-
|
| 87 |
-
All HTTP requests are logged with:
|
| 88 |
-
- `[REQUEST]` - Incoming request (method, path)
|
| 89 |
-
- `[RESPONSE]` - Response status and duration
|
| 90 |
-
|
| 91 |
-
Example:
|
| 92 |
-
```
|
| 93 |
-
[REQUEST] method=GET path=/
|
| 94 |
-
[RESPONSE] method=GET path=/ status=307 duration=0.015s
|
| 95 |
-
```
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: mbok_dev
|
| 3 |
+
emoji: ๐
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: green
|
| 6 |
+
sdk: docker
|
| 7 |
+
pinned: false
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
# mbok_dev
|
| 11 |
+
|
| 12 |
+
Public gateway with Supabase authentication that dynamically loads the private ver20 application from `DLPO/habadashi` Space.
|
| 13 |
+
|
| 14 |
+
## Features
|
| 15 |
+
|
| 16 |
+
- Supabase email/password authentication
|
| 17 |
+
- Cookie-based session management
|
| 18 |
+
- Dynamic loading of private application code (source code not exposed in public repo)
|
| 19 |
+
- Role-based access control via profiles table
|
| 20 |
+
|
| 21 |
+
## Environment Variables (Set in HF Space Secrets)
|
| 22 |
+
|
| 23 |
+
- `SUPABASE_URL`: Your Supabase project URL
|
| 24 |
+
- `SUPABASE_KEY`: Your Supabase anon/service key
|
| 25 |
+
- `HF_TOKEN`: Hugging Face token with access to private `DLPO/habadashi` Space
|
| 26 |
+
- `OPENAI_KEY`: OpenAI API key (required by ver20)
|
| 27 |
+
- `CLIENTPOOL`: Client pool configuration (required by ver20)
|
| 28 |
+
|
| 29 |
+
## Architecture
|
| 30 |
+
|
| 31 |
+
1. User visits public Space
|
| 32 |
+
2. Bootstrap downloads ver20 from private `DLPO/habadashi` Space
|
| 33 |
+
3. User logs in with Supabase credentials
|
| 34 |
+
4. On successful login, ver20 Gradio app is mounted at `/app/`
|
| 35 |
+
5. User profile and organization info loaded from `profiles` table
|
| 36 |
+
|
| 37 |
+
## Startup Phase Logging
|
| 38 |
+
|
| 39 |
+
The application logs structured startup phases to help diagnose issues. Look for these phase markers in the logs:
|
| 40 |
+
|
| 41 |
+
### Expected Startup Sequence
|
| 42 |
+
|
| 43 |
+
1. `[STARTUP_META]` - Environment and configuration info
|
| 44 |
+
2. `[PHASE] bootstrap_start` - Begin downloading private app
|
| 45 |
+
3. `[PHASE] bootstrap_end success=true` - Private app downloaded
|
| 46 |
+
4. `[PHASE] supabase_init_start` - Initialize Supabase client
|
| 47 |
+
5. `[PHASE] supabase_init_end success=true` - Supabase ready
|
| 48 |
+
6. `[PHASE] fastapi_init_start/end` - FastAPI app created
|
| 49 |
+
7. `[PHASE] create_ui_start/end` - Login UI created
|
| 50 |
+
8. `[PHASE] import_ver20_start` - Import ver20 app
|
| 51 |
+
9. `[PHASE] import_ver20_end success=true` - Ver20 loaded
|
| 52 |
+
10. `[PHASE] mount_login_start/end` - Login UI mounted
|
| 53 |
+
11. `[PHASE] mount_app_start/end` - Ver20 app mounted
|
| 54 |
+
12. `[STARTUP_COMPLETE]` - All phases complete
|
| 55 |
+
|
| 56 |
+
### Health Check Endpoint
|
| 57 |
+
|
| 58 |
+
Once started, check the health endpoint:
|
| 59 |
+
|
| 60 |
+
```bash
|
| 61 |
+
curl https://DLPO-mbok-dev.hf.space/healthz
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
Expected response:
|
| 65 |
+
```json
|
| 66 |
+
{
|
| 67 |
+
"ok": true,
|
| 68 |
+
"ver20_loaded": true,
|
| 69 |
+
"private_app_dir": "./private_app"
|
| 70 |
+
}
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
### Debugging Startup Failures
|
| 74 |
+
|
| 75 |
+
If the Space fails to start or restarts repeatedly:
|
| 76 |
+
|
| 77 |
+
1. **Check the last phase reached** in logs
|
| 78 |
+
2. **Look for `[ERROR]` and `[TRACEBACK]` markers** after the last phase
|
| 79 |
+
3. **Common failure points:**
|
| 80 |
+
- `bootstrap_end success=false` - HF_TOKEN missing or invalid
|
| 81 |
+
- `supabase_init_end success=false` - SUPABASE_URL/KEY missing
|
| 82 |
+
- `import_ver20_end success=false` - Ver20 app.py structure issue
|
| 83 |
+
- No phases after `mount_app_end` - Port binding or health check issue
|
| 84 |
+
|
| 85 |
+
### Request Logging
|
| 86 |
+
|
| 87 |
+
All HTTP requests are logged with:
|
| 88 |
+
- `[REQUEST]` - Incoming request (method, path)
|
| 89 |
+
- `[RESPONSE]` - Response status and duration
|
| 90 |
+
|
| 91 |
+
Example:
|
| 92 |
+
```
|
| 93 |
+
[REQUEST] method=GET path=/
|
| 94 |
+
[RESPONSE] method=GET path=/ status=307 duration=0.015s
|
| 95 |
+
```
|
app.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
-
|
| 4 |
Public Space that loads private ver20 app dynamically
|
| 5 |
"""
|
| 6 |
|
|
@@ -26,7 +26,7 @@ from supabase_logger import init_logger, log_event, set_user_context, get_user_c
|
|
| 26 |
|
| 27 |
# --- Startup Meta Info ---
|
| 28 |
print("=" * 80)
|
| 29 |
-
print("๐ Starting
|
| 30 |
print("=" * 80)
|
| 31 |
print(f"[STARTUP_META] Python version: {sys.version}")
|
| 32 |
print(f"[STARTUP_META] CWD: {os.getcwd()}")
|
|
@@ -554,7 +554,7 @@ else:
|
|
| 554 |
print("[PHASE] mount_app_end path=/app protected=true ver20=false fallback=true")
|
| 555 |
|
| 556 |
print("=" * 80)
|
| 557 |
-
print("๐
|
| 558 |
print("=" * 80)
|
| 559 |
print(f"[STARTUP_COMPLETE] All phases completed successfully")
|
| 560 |
print(f"[STARTUP_COMPLETE] Access URLs:")
|
|
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
+
mbok_dev - Main entry point
|
| 4 |
Public Space that loads private ver20 app dynamically
|
| 5 |
"""
|
| 6 |
|
|
|
|
| 26 |
|
| 27 |
# --- Startup Meta Info ---
|
| 28 |
print("=" * 80)
|
| 29 |
+
print("๐ Starting mbok_dev")
|
| 30 |
print("=" * 80)
|
| 31 |
print(f"[STARTUP_META] Python version: {sys.version}")
|
| 32 |
print(f"[STARTUP_META] CWD: {os.getcwd()}")
|
|
|
|
| 554 |
print("[PHASE] mount_app_end path=/app protected=true ver20=false fallback=true")
|
| 555 |
|
| 556 |
print("=" * 80)
|
| 557 |
+
print("๐ mbok_dev Ready!")
|
| 558 |
print("=" * 80)
|
| 559 |
print(f"[STARTUP_COMPLETE] All phases completed successfully")
|
| 560 |
print(f"[STARTUP_COMPLETE] Access URLs:")
|
bootstrap.py
CHANGED
|
@@ -1,12 +1,21 @@
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
-
Bootstrap module - Downloads ver20 from private
|
|
|
|
|
|
|
| 4 |
"""
|
| 5 |
|
| 6 |
import os
|
| 7 |
from pathlib import Path
|
| 8 |
from huggingface_hub import snapshot_download
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
def get_hf_token():
|
| 11 |
"""Get HF_TOKEN from environment variable"""
|
| 12 |
token = os.environ.get("HF_TOKEN")
|
|
@@ -21,15 +30,18 @@ def get_hf_token():
|
|
| 21 |
|
| 22 |
def download_private_app(force_download: bool = False):
|
| 23 |
"""
|
| 24 |
-
Download ver20 application from private
|
| 25 |
-
|
|
|
|
|
|
|
|
|
|
| 26 |
Args:
|
| 27 |
force_download: If True, re-download even if already cached
|
| 28 |
-
|
| 29 |
Returns:
|
| 30 |
Path: Local directory containing downloaded ver20 files
|
| 31 |
"""
|
| 32 |
-
repo_id =
|
| 33 |
repo_type = "space"
|
| 34 |
local_dir = Path("./private_app")
|
| 35 |
|
|
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
+
Bootstrap module - Downloads ver20 from private Space.
|
| 4 |
+
mbok_dev / mbok-dev โ DLPO/habadashi_dev
|
| 5 |
+
mbok (ใใฎไป) โ DLPO/habadashi
|
| 6 |
"""
|
| 7 |
|
| 8 |
import os
|
| 9 |
from pathlib import Path
|
| 10 |
from huggingface_hub import snapshot_download
|
| 11 |
|
| 12 |
+
def _resolve_repo_id() -> str:
|
| 13 |
+
"""SPACE_ID ็ฐๅขๅคๆฐใใๅ็
งๅ
private Space ใฎ repo_id ใๆฑบๅฎใใใ"""
|
| 14 |
+
space_id = os.environ.get("SPACE_ID", "").lower()
|
| 15 |
+
if "mbok_dev" in space_id or "mbok-dev" in space_id:
|
| 16 |
+
return "DLPO/habadashi_dev"
|
| 17 |
+
return "DLPO/habadashi"
|
| 18 |
+
|
| 19 |
def get_hf_token():
|
| 20 |
"""Get HF_TOKEN from environment variable"""
|
| 21 |
token = os.environ.get("HF_TOKEN")
|
|
|
|
| 30 |
|
| 31 |
def download_private_app(force_download: bool = False):
|
| 32 |
"""
|
| 33 |
+
Download ver20 application from private Space.
|
| 34 |
+
ๅ็
งๅ
ใฏ SPACE_ID ็ฐๅขๅคๆฐใงๆฑบๅฎ:
|
| 35 |
+
mbok_dev / mbok-dev โ DLPO/habadashi_dev
|
| 36 |
+
mbok (ใใฎไป) โ DLPO/habadashi
|
| 37 |
+
|
| 38 |
Args:
|
| 39 |
force_download: If True, re-download even if already cached
|
| 40 |
+
|
| 41 |
Returns:
|
| 42 |
Path: Local directory containing downloaded ver20 files
|
| 43 |
"""
|
| 44 |
+
repo_id = _resolve_repo_id()
|
| 45 |
repo_type = "space"
|
| 46 |
local_dir = Path("./private_app")
|
| 47 |
|