eduardo4547 commited on
Commit
499671b
·
verified ·
1 Parent(s): 17e98a3

Upload 278 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +5 -0
  2. README.md +180 -131
  3. backend/.env +4 -0
  4. backend/__pycache__/main.cpython-312.pyc +0 -0
  5. backend/core/__pycache__/config.cpython-312.pyc +0 -0
  6. backend/core/config.py +5 -0
  7. backend/logs/app.log +213 -0
  8. backend/requirements.txt +11 -15
  9. backend/routers/__pycache__/auth.cpython-312.pyc +0 -0
  10. backend/routers/__pycache__/catalog.cpython-312.pyc +0 -0
  11. backend/routers/__pycache__/pages.cpython-312.pyc +0 -0
  12. backend/routers/__pycache__/segmentation.cpython-312.pyc +0 -0
  13. backend/routers/catalog.py +0 -126
  14. backend/services/__pycache__/gradio_client_service.cpython-312.pyc +0 -0
  15. backend/services/__pycache__/image_service.cpython-312.pyc +0 -0
  16. backend/services/__pycache__/sam2_service.cpython-312.pyc +0 -0
  17. backend/services/__pycache__/scene_service.cpython-312.pyc +0 -0
  18. backend/services/__pycache__/segmentation_service.cpython-312.pyc +0 -0
  19. backend/services/__pycache__/texture_service.cpython-312.pyc +0 -0
  20. backend/services/gradio_client_service.py +93 -0
  21. backend/services/image_service.py +12 -2
  22. backend/services/sam2_service.py +41 -24
  23. backend/services/segmentation_service.py +6 -1
  24. backend/uploads/demo-room.jpg +3 -0
  25. backend/uploads/demo-room_edit_007d1456.jpg +0 -0
  26. backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2.jpg +0 -0
  27. backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1.jpg +0 -0
  28. backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006.jpg +0 -0
  29. backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74.jpg +0 -0
  30. backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc.jpg +0 -0
  31. backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6.jpg +0 -0
  32. backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6_edit_78068a16.jpg +0 -0
  33. backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6_edit_78068a16_edit_bc375f53.jpg +0 -0
  34. backend/uploads/demo-room_edit_09a864d7.jpg +0 -0
  35. backend/uploads/demo-room_edit_09a864d7_edit_a3f60d46.jpg +0 -0
  36. backend/uploads/demo-room_edit_09a864d7_edit_a3f60d46_edit_eecc8494.jpg +0 -0
  37. backend/uploads/demo-room_edit_09a864d7_edit_a3f60d46_edit_eecc8494_edit_310aa4a1.jpg +0 -0
  38. backend/uploads/demo-room_edit_ef2b9c2c.jpg +3 -0
  39. backend/uploads/demo-room_edit_ef2b9c2c_edit_32b3c807.jpg +3 -0
  40. backend/uploads/demo-room_edit_ef2b9c2c_edit_32b3c807_edit_e6f30d22.jpg +3 -0
  41. backend/uploads/demo-room_edit_f6aa2f46.jpg +0 -0
  42. backend/uploads/demo-room_edit_f6aa2f46_edit_2063dc93.jpg +0 -0
  43. backend/uploads/demo-room_edit_f6aa2f46_edit_2063dc93_edit_c151acb0.jpg +0 -0
  44. backend/uploads/demo-room_edit_f6aa2f46_edit_2063dc93_edit_c151acb0_edit_fb84149e.jpg +0 -0
  45. backend/uploads/masks/demo-room.jpg_labels.png +0 -0
  46. backend/uploads/masks/demo-room.jpg_labels_meta.json +1 -0
  47. backend/uploads/masks/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6_edit_78068a16_edit_bc375f53_labels.png +0 -0
  48. backend/uploads/masks/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6_edit_78068a16_labels.png +0 -0
  49. backend/uploads/masks/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6_labels.png +0 -0
  50. backend/uploads/masks/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_labels.png +0 -0
.gitattributes CHANGED
@@ -142,3 +142,8 @@ frontend/src/assets/imagens-default-room/terrace/terrace2.png filter=lfs diff=lf
142
  frontend/src/assets/imagens-default-room/terrace/terrace3.png filter=lfs diff=lfs merge=lfs -text
143
  frontend/src/assets/imagens-default-room/terrace/terrace4.png filter=lfs diff=lfs merge=lfs -text
144
  frontend/src/assets/imagens-default-room/terrace/terrace5.png filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
142
  frontend/src/assets/imagens-default-room/terrace/terrace3.png filter=lfs diff=lfs merge=lfs -text
143
  frontend/src/assets/imagens-default-room/terrace/terrace4.png filter=lfs diff=lfs merge=lfs -text
144
  frontend/src/assets/imagens-default-room/terrace/terrace5.png filter=lfs diff=lfs merge=lfs -text
145
+ backend/uploads/demo-room_edit_ef2b9c2c_edit_32b3c807_edit_e6f30d22.jpg filter=lfs diff=lfs merge=lfs -text
146
+ backend/uploads/demo-room_edit_ef2b9c2c_edit_32b3c807.jpg filter=lfs diff=lfs merge=lfs -text
147
+ backend/uploads/demo-room_edit_ef2b9c2c.jpg filter=lfs diff=lfs merge=lfs -text
148
+ backend/uploads/demo-room.jpg filter=lfs diff=lfs merge=lfs -text
149
+ backend/uploads/proyecto-White-Houses_edit_d4a831c5_edit_c5a95477.jpg filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,131 +1,180 @@
1
- ---
2
- title: Hyper Reality Room Visualizer
3
- emoji: 🏠
4
- colorFrom: blue
5
- colorTo: indigo
6
- sdk: docker
7
- app_port: 7860
8
- pinned: false
9
- ---
10
-
11
- # PoC SaaS Iframe
12
-
13
- Este repositorio es una prueba de concepto de un SaaS que ofrece un visualizador embebido mediante iframe.
14
-
15
- ## Visión general
16
-
17
- El proyecto está dividido en dos partes principales:
18
-
19
- - `backend/` - servidor en Python con FastAPI que expone APIs, sirve el build de React en producción y controla la seguridad.
20
- - `frontend/` - aplicación React creada con Vite que funciona como visualizador embebido.
21
-
22
- Además existen carpetas de ejemplos de cliente:
23
-
24
- - `cliente1/`, `cliente2/`, `cliente3/`
25
-
26
- Estas páginas muestran cómo integrar el widget del SaaS desde un host externo.
27
-
28
- ## Documentación del proyecto
29
-
30
- - Documentación general: este archivo `README.md`
31
- - Documentación del backend: `backend/README.md`
32
-
33
- ## Arquitectura
34
-
35
- 1. El backend maneja:
36
- - `POST /api/token` para generar tokens temporales
37
- - `GET /config` para devolver datos del cliente
38
- - `POST /session/start` para registrar sesiones activas
39
- - `/app` para servir el frontend construido en producción
40
- - `/widget.js` para el widget que inyecta el iframe en clientes externos
41
-
42
- 2. El frontend React se ejecuta en dos modos:
43
- - desarrollo (`npm run dev` en `frontend/`) para cambios rápidos y hot reload
44
- - producción (`npm run build`) produce `frontend/dist`, que el backend sirve como estático
45
-
46
- 3. El widget cliente solicita un token al backend y luego inyecta un iframe con `/app?token=...`.
47
-
48
- ## Flujo de desarrollo
49
-
50
- Este proyecto tiene dos flujos claros de desarrollo:
51
-
52
- 1. Desarrollo frontend con Vite
53
- 2. Desarrollo backend con FastAPI
54
-
55
- Ambos pueden correr al mismo tiempo para que los devs trabajen en el app y en la API al mismo tiempo.
56
-
57
- ### Flujo recomendado para desarrollo local
58
-
59
- 1. Abrir una terminal para el backend:
60
-
61
- ```cmd
62
- cd /d C:\Users\alane\OneDrive\Escritorio\Prueba-PoC\backend
63
- .venv\Scripts\activate
64
- pip install -r requirements.txt
65
- python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000
66
- ```
67
-
68
- 2. Abrir otra terminal para el frontend:
69
-
70
- ```cmd
71
- cd /d C:\Users\alane\OneDrive\Escritorio\Prueba-PoC\frontend
72
- npm install
73
- npm run dev
74
- ```
75
-
76
- 3. Cargar el app React en el navegador para ver hot reload:
77
-
78
- - `http://localhost:5173/app?token=...`
79
-
80
- 4. Si necesitas probar la integración completa con el backend y los endpoints, usa también:
81
-
82
- - `http://localhost:8000/preview`
83
- - `http://localhost:8000/admin`
84
-
85
- ### Qué significa este flujo
86
-
87
- - `localhost:5173` sirve el frontend en modo desarrollo con hot reload.
88
- - `localhost:8000` sirve el backend y, en producción, también el build estático de React.
89
- - Durante el desarrollo, no necesitas ejecutar `npm run build` cada vez que cambias `frontend/src`.
90
- - El build solo es necesario cuando quieres probar la app servida desde el backend (`/app`) o cuando subes a producción.
91
-
92
- ### Desarrollo incremental
93
-
94
- - Cambia archivos en `frontend/src` y Vite recargará el navegador automáticamente.
95
- - Cambia `backend/main.py` y Uvicorn recargará el backend automáticamente.
96
- - Si quieres probar una ruta de frontend específica desde el backend, primero construye y luego carga `http://localhost:8000/app?token=...`.
97
-
98
- ### Integración en producción
99
-
100
- Cuando ya estés listo para producción o para una prueba final:
101
-
102
- ```cmd
103
- cd /d C:\Users\alane\OneDrive\Escritorio\Prueba-PoC\frontend
104
- npm run build
105
- ```
106
-
107
- Luego abre:
108
-
109
- - `http://localhost:8000/app?token=...`
110
-
111
- En este modo, el backend sirve los archivos estáticos desde `frontend/dist`.
112
-
113
- ## Comandos útiles
114
-
115
- - `npm run dev` - desarrollo React con Vite
116
- - `npm run build` - generar `frontend/dist`
117
- - `python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000` - arrancar backend
118
- - `run_server.bat` - helper Windows para iniciar el backend con `.venv`
119
-
120
- ## Estructura de carpetas
121
-
122
- - `backend/` - servidor FastAPI, documentos y páginas auxiliares
123
- - `frontend/` - app React + Vite
124
- - `frontend/dist/` - build de producción
125
- - `cliente1/`, `cliente2/`, `cliente3/` - ejemplos de integración
126
-
127
- ## Importante
128
-
129
- - En desarrollo, usa `localhost:5173` para ver los cambios de frontend al instante.
130
- - En producción, el backend sirve todos los assets desde `frontend/dist` en `/app`.
131
- - `backend/README.md` contiene la documentación técnica detallada del backend.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Hyper Reality Room Visualizer
3
+ emoji: 🏠
4
+ colorFrom: blue
5
+ colorTo: indigo
6
+ sdk: docker
7
+ app_port: 7860
8
+ pinned: false
9
+ ---
10
+
11
+ # Hyper Reality Room Visualizer — PoC SaaS
12
+
13
+ Visualizador de habitaciones embebido como SaaS mediante iframe. Los clientes reciben una API key y un snippet HTML; el backend genera un token temporal y carga el visualizador en un iframe.
14
+
15
+ ## Estructura del repositorio
16
+
17
+ ```
18
+ Prueba-PoC/
19
+ ├── backend/ # FastAPI API, autenticación, SAM2, texturas
20
+ │ ├── main.py
21
+ │ ├── routers/
22
+ │ ├── services/
23
+ │ ├── requirements.txt
24
+ │ ├── .env # variables locales (no se sube a git)
25
+ │ └── Dockerfile # usado solo por docker-compose (desarrollo local)
26
+ ├── frontend/ # React + Vite visualizador embebido
27
+ │ ├── src/
28
+ │ ├── package.json
29
+ │ └── dist/ # generado por npm run build (ignorado en git)
30
+ ├── Dockerfile # multi-stage para HuggingFace Spaces
31
+ ├── docker-compose.yml # entorno local con Docker
32
+ └── README.md
33
+ ```
34
+
35
+ ## Arquitectura
36
+
37
+ ```
38
+ Cliente externo (HTML del cliente)
39
+ └─► widget.js — se auto-descarga desde el servidor
40
+ └─► POST /api/token — obtiene token temporal
41
+ └─► <iframe src="/app?token=...">
42
+ └─► FastAPI sirve index.html del SPA React
43
+ └─► SPA carga assets desde /assets/...
44
+ ```
45
+
46
+ El backend expone:
47
+
48
+ | Endpoint | Descripción |
49
+ |---|---|
50
+ | `POST /api/token` | Genera token temporal (TTL 5 min) |
51
+ | `GET /config` | Devuelve datos del cliente validando token |
52
+ | `POST /session/start` | Registra sesión activa |
53
+ | `GET /widget.js` | Script que el cliente externo incluye en su HTML |
54
+ | `GET /admin` | Panel de gestión de API keys |
55
+ | `GET /app` | Punto de entrada del SPA React |
56
+ | `POST /api/generate-key` | Crea nueva API key (persiste en MongoDB) |
57
+ | `DELETE /api/keys/{id}` | Elimina API key |
58
+
59
+ ## Variables de entorno
60
+
61
+ Crea el archivo `backend/.env` (ya está en `.gitignore`):
62
+
63
+ ```env
64
+ MONGODB_URI=mongodb+srv://<usuario>:<password>@<cluster>.mongodb.net/
65
+ ```
66
+
67
+ En **HuggingFace Spaces**: Settings → Repository secrets → `MONGODB_URI`.
68
+
69
+ ## Desarrollo local
70
+
71
+ Hay dos opciones: con o sin Docker.
72
+
73
+ ### Opción A — Sin Docker (recomendado para desarrollo activo)
74
+
75
+ Levanta backend y frontend en terminales separadas para obtener hot reload en ambos.
76
+
77
+ **Terminal 1 — Backend:**
78
+
79
+ ```bash
80
+ cd backend
81
+ python -m venv .venv
82
+ .venv\Scripts\activate # Windows
83
+ # source .venv/bin/activate # Mac / Linux
84
+ pip install -r requirements.txt
85
+ python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000
86
+ ```
87
+
88
+ **Terminal 2 Frontend:**
89
+
90
+ ```bash
91
+ cd frontend
92
+ npm install
93
+ npm run dev
94
+ ```
95
+
96
+ **URLs disponibles:**
97
+
98
+ | URL | Qué muestra |
99
+ |---|---|
100
+ | `http://localhost:5173/app` | SPA React con hot reload (Vite dev server) |
101
+ | `http://localhost:8000/admin` | Panel de API keys |
102
+ | `http://localhost:8000/preview` | Vista previa del iframe |
103
+
104
+ El frontend en `localhost:5173` proxea automáticamente `/api`, `/seg`, `/uploads` y `/widget.js` hacia `localhost:8000` (configurado en `vite.config.ts`).
105
+
106
+ ### Opción B — Con Docker Compose
107
+
108
+ Levanta solo el backend en contenedor. Útil para probar la integración completa.
109
+
110
+ ```bash
111
+ docker compose up --build
112
+ ```
113
+
114
+ Accede en `http://localhost:8000`. El frontend se sirve desde `frontend/dist` montado como volumen — necesitas haber ejecutado `npm run build` antes.
115
+
116
+ ## Integración completa (backend sirve el frontend)
117
+
118
+ Cuando quieres probar exactamente como quedaría en producción:
119
+
120
+ ```bash
121
+ # 1. Construir el frontend
122
+ cd frontend
123
+ npm run build
124
+
125
+ # 2. Levantar el backend (sirve frontend/dist en /app)
126
+ cd ../backend
127
+ python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000
128
+ ```
129
+
130
+ Abre `http://localhost:8000/app` el backend sirve los assets estáticos desde `frontend/dist`.
131
+
132
+ ## Despliegue en HuggingFace Spaces
133
+
134
+ El `Dockerfile` de la raíz es el que usa HuggingFace. Hace dos cosas:
135
+
136
+ 1. **Stage 1 (Node):** ejecuta `npm run build` y produce `frontend/dist`
137
+ 2. **Stage 2 (Python):** instala dependencias del backend y copia el dist del stage 1
138
+
139
+ No necesitas subir `frontend/dist` al repositorio — Docker lo genera automáticamente en cada push.
140
+
141
+ ```bash
142
+ git add .
143
+ git commit -m "tu mensaje"
144
+ git push
145
+ ```
146
+
147
+ HuggingFace detecta el push y reconstruye el contenedor.
148
+
149
+ **URL del Space:** `https://huggingface.co/spaces/eduardo4547/hyper-reality-visualizer`
150
+
151
+ ## Flujo del widget para clientes externos
152
+
153
+ El cliente externo pega este snippet en su HTML (se obtiene desde `/admin`):
154
+
155
+ ```html
156
+ <div id="contenedor-saas" data-client-id="CLIENTE_XXXXXXXX"></div>
157
+ <script src="https://<tu-space>.hf.space/widget.js"></script>
158
+ ```
159
+
160
+ El script:
161
+ 1. Lee `data-client-id` del div
162
+ 2. Llama `POST /api/token` con ese ID
163
+ 3. Inyecta un `<iframe>` apuntando a `/app?token=<token>`
164
+
165
+ ## Comandos útiles
166
+
167
+ ```bash
168
+ # Backend
169
+ python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000
170
+
171
+ # Frontend — desarrollo
172
+ npm run dev
173
+
174
+ # Frontend — producción
175
+ npm run build
176
+
177
+ # Docker local
178
+ docker compose up --build
179
+ docker compose down
180
+ ```
backend/.env CHANGED
@@ -1 +1,5 @@
1
  MONGODB_URI=mongodb+srv://alaneduardodelacruz407_db_user:YGUWdpXqUiGH104Q@naufar-cluster.n9htwoa.mongodb.net/
 
 
 
 
 
1
  MONGODB_URI=mongodb+srv://alaneduardodelacruz407_db_user:YGUWdpXqUiGH104Q@naufar-cluster.n9htwoa.mongodb.net/
2
+ # Para producción (HuggingFace):
3
+ GRADIO_SPACE_URL=https://eduardo4547-hyper-reality-sam2-gpu.hf.space
4
+ # Para desarrollo local (Gradio corriendo en puerto 7860):
5
+ # GRADIO_SPACE_URL=http://localhost:7860
backend/__pycache__/main.cpython-312.pyc CHANGED
Binary files a/backend/__pycache__/main.cpython-312.pyc and b/backend/__pycache__/main.cpython-312.pyc differ
 
backend/core/__pycache__/config.cpython-312.pyc CHANGED
Binary files a/backend/core/__pycache__/config.cpython-312.pyc and b/backend/core/__pycache__/config.cpython-312.pyc differ
 
backend/core/config.py CHANGED
@@ -51,6 +51,11 @@ SAM2_MODEL_DIR_CANDIDATES = ("models", "modelo")
51
  SAM2_UNLOAD_AFTER_USE = str(os.getenv("SAM2_UNLOAD_AFTER_USE", "0")).strip().lower() in {"1", "true", "yes"}
52
  FRONTEND_DEBUG = str(os.getenv("FRONTEND_DEBUG", "0")).strip().lower() in {"1", "true", "yes", "on"}
53
 
 
 
 
 
 
54
  MAX_UPLOAD_WIDTH = 1024
55
  UPLOAD_JPEG_QUALITY = 82
56
  SD_JOB_STALE_SECONDS = 120
 
51
  SAM2_UNLOAD_AFTER_USE = str(os.getenv("SAM2_UNLOAD_AFTER_USE", "0")).strip().lower() in {"1", "true", "yes"}
52
  FRONTEND_DEBUG = str(os.getenv("FRONTEND_DEBUG", "0")).strip().lower() in {"1", "true", "yes", "on"}
53
 
54
+ # URL del Space de Gradio que procesa las imágenes con GPU.
55
+ # Local: http://localhost:7860
56
+ # Producción: https://<tu-space>.hf.space
57
+ GRADIO_SPACE_URL: str = os.getenv("GRADIO_SPACE_URL", "").rstrip("/")
58
+
59
  MAX_UPLOAD_WIDTH = 1024
60
  UPLOAD_JPEG_QUALITY = 82
61
  SD_JOB_STALE_SECONDS = 120
backend/logs/app.log CHANGED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2026-04-29 20:12:40,375 INFO backend.segmentation: [LIFESPAN] GRADIO_SPACE_URL set — skipping local SAM2 load.
2
+ 2026-04-29 20:13:22,434 INFO pymongo.serverSelection: {"message": "Waiting for suitable server to become available", "selector": "Primary()", "operation": "find", "topologyDescription": "<TopologyDescription id: 69f2bac20e0544b45d45e6f1, topology_type: ReplicaSetNoPrimary, servers: [<ServerDescription ('ac-tynjizz-shard-00-00.n9htwoa.mongodb.net', 27017) server_type: Unknown, rtt: None>, <ServerDescription ('ac-tynjizz-shard-00-01.n9htwoa.mongodb.net', 27017) server_type: Unknown, rtt: None>, <ServerDescription ('ac-tynjizz-shard-00-02.n9htwoa.mongodb.net', 27017) server_type: Unknown, rtt: None>]>", "clientId": {"$oid": "69f2bac20e0544b45d45e6f1"}, "remainingTimeMS": 30}
3
+ 2026-04-29 20:13:53,491 INFO backend.segmentation: [UPLOAD_BG] START at 2026-04-30T02:13:53.491443+00:00
4
+ 2026-04-29 20:13:53,492 INFO backend.segmentation: [JOB 667a8562af1044a6926d53449b625dd6] preparing_image progress=12
5
+ 2026-04-29 20:13:53,743 INFO backend.segmentation: [JOB 667a8562af1044a6926d53449b625dd6] segmenting_with_sam2 progress=30 estimated_seconds=51.939840000000004
6
+ 2026-04-29 20:13:56,153 INFO httpx: HTTP Request: GET https://eduardo4547-hyper-reality-sam2-gpu.hf.space/config "HTTP/1.1 200 OK"
7
+ 2026-04-29 20:13:56,625 INFO httpx: HTTP Request: GET https://eduardo4547-hyper-reality-sam2-gpu.hf.space/gradio_api/info?serialize=False "HTTP/1.1 200 OK"
8
+ 2026-04-29 20:13:56,675 WARNING services.gradio_client_service: Gradio Space call failed, falling back to local SAM2: Cannot find a function with `api_name`: /segment.
9
+ 2026-04-29 20:13:56,675 INFO backend.segmentation: [SAM2_GENERATE] START at 2026-04-30T02:13:56.675848+00:00
10
+ 2026-04-29 20:13:56,687 INFO backend.segmentation: [SAM2] Mask generator not loaded; attempting on-demand load.
11
+ 2026-04-29 20:13:56,687 WARNING backend.segmentation: [SAM2] torch not installed — SAM2 unavailable (using Gradio Space)
12
+ 2026-04-29 20:13:56,687 ERROR backend.segmentation: [JOB 667a8562af1044a6926d53449b625dd6] failed: 500: torch not installed — SAM2 unavailable (using Gradio Space)
13
+ Traceback (most recent call last):
14
+ File "C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\services\image_service.py", line 145, in run_upload_job
15
+ label_map, mask_count = generate_label_map(image_rgb)
16
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17
+ File "C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\services\scene_service.py", line 134, in generate_label_map
18
+ generator = get_sam2_mask_generator()
19
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
20
+ File "C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\services\sam2_service.py", line 184, in get_sam2_mask_generator
21
+ raise HTTPException(status_code=500, detail=detail)
22
+ fastapi.exceptions.HTTPException: 500: torch not installed — SAM2 unavailable (using Gradio Space)
23
+ 2026-04-29 20:13:56,689 INFO backend.segmentation: [UPLOAD_BG] DONE 3.196s at 2026-04-30T02:13:56.689353+00:00
24
+ 2026-04-29 20:13:56,689 INFO backend.segmentation: Releasing resources (full_unload=False)
25
+ 2026-04-29 20:13:57,044 INFO httpx: HTTP Request: HEAD https://huggingface.co/api/telemetry/py_client/initiated "HTTP/1.1 200 OK"
26
+ 2026-04-29 20:13:57,163 INFO httpx: HTTP Request: GET https://eduardo4547-hyper-reality-sam2-gpu.hf.space/gradio_api/heartbeat/68121945-8a97-442e-8cbb-59cd817f9df3 "HTTP/1.1 200 OK"
27
+ 2026-04-29 20:16:38,951 INFO backend.segmentation: [LIFESPAN] GRADIO_SPACE_URL set — skipping local SAM2 load.
28
+ 2026-04-29 20:16:55,032 INFO backend.segmentation: [UPLOAD_BG] START at 2026-04-30T02:16:55.032702+00:00
29
+ 2026-04-29 20:16:55,032 INFO backend.segmentation: [JOB 50d2907ecb844a3fafc2f8a5247620ea] preparing_image progress=12
30
+ 2026-04-29 20:16:55,089 INFO backend.segmentation: [JOB 50d2907ecb844a3fafc2f8a5247620ea] segmenting_with_sam2 progress=30 estimated_seconds=51.939840000000004
31
+ 2026-04-29 20:16:57,866 INFO httpx: HTTP Request: GET http://localhost:7860/config "HTTP/1.1 200 OK"
32
+ 2026-04-29 20:17:00,098 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/info?serialize=False "HTTP/1.1 200 OK"
33
+ 2026-04-29 20:17:00,613 INFO httpx: HTTP Request: HEAD https://huggingface.co/api/telemetry/py_client/initiated "HTTP/1.1 200 OK"
34
+ 2026-04-29 20:17:02,540 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/heartbeat/06d3302a-135c-423c-8294-e950bff0a17a "HTTP/1.1 200 OK"
35
+ 2026-04-29 20:17:02,542 INFO httpx: HTTP Request: POST http://localhost:7860/gradio_api/upload "HTTP/1.1 200 OK"
36
+ 2026-04-29 20:17:04,774 INFO httpx: HTTP Request: POST http://localhost:7860/gradio_api/queue/join "HTTP/1.1 200 OK"
37
+ 2026-04-29 20:17:07,079 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/queue/data?session_hash=06d3302a-135c-423c-8294-e950bff0a17a "HTTP/1.1 200 OK"
38
+ 2026-04-29 20:17:26,593 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/file=C:\Users\alane\AppData\Local\Temp\gradio\b17b68f6472ad2c6c0bb7499f231e242c50b344237d319bd3b45d56ef2d488aa\image.webp "HTTP/1.1 200 OK"
39
+ 2026-04-29 20:17:26,607 INFO services.gradio_client_service: Gradio Space segmentation: entorno=🌳 Terraza / Patio / Jardín motor=Híbrido Arquitectura (Cityscapes Grande + DINO Pequeño) mask_count=20
40
+ 2026-04-29 20:17:26,607 INFO backend.segmentation: [JOB 50d2907ecb844a3fafc2f8a5247620ea] saving_masks progress=92
41
+ 2026-04-29 20:17:26,690 INFO backend.segmentation: [JOB 50d2907ecb844a3fafc2f8a5247620ea] segments_meta saved (20 segments)
42
+ 2026-04-29 20:17:26,690 INFO backend.segmentation: [JOB 50d2907ecb844a3fafc2f8a5247620ea] done mask_count=20
43
+ 2026-04-29 20:17:26,691 INFO backend.segmentation: [UPLOAD_BG] DONE 31.658s at 2026-04-30T02:17:26.691033+00:00
44
+ 2026-04-29 20:17:26,691 INFO backend.segmentation: Releasing resources (full_unload=False)
45
+ 2026-04-29 20:17:45,867 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:17:45.867306+00:00
46
+ 2026-04-29 20:17:46,402 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\proyecto-White-Houses.jpg
47
+ 2026-04-29 20:17:46,702 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.835s at 2026-04-30T02:17:46.702156+00:00
48
+ 2026-04-29 20:17:50,496 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:17:50.496976+00:00
49
+ 2026-04-29 20:17:50,819 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\proyecto-White-Houses.jpg
50
+ 2026-04-29 20:17:50,985 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.488s at 2026-04-30T02:17:50.985122+00:00
51
+ 2026-04-29 20:17:54,307 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:17:54.307539+00:00
52
+ 2026-04-29 20:17:54,768 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\proyecto-White-Houses.jpg
53
+ 2026-04-29 20:17:54,931 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.624s at 2026-04-30T02:17:54.931489+00:00
54
+ 2026-04-29 20:17:56,247 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:17:56.247254+00:00
55
+ 2026-04-29 20:17:56,728 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\proyecto-White-Houses.jpg
56
+ 2026-04-29 20:17:56,898 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.651s at 2026-04-30T02:17:56.898353+00:00
57
+ 2026-04-29 20:18:00,146 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:18:00.146989+00:00
58
+ 2026-04-29 20:18:00,616 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\proyecto-White-Houses.jpg
59
+ 2026-04-29 20:18:00,782 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.636s at 2026-04-30T02:18:00.782444+00:00
60
+ 2026-04-29 20:18:05,560 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:18:05.560412+00:00
61
+ 2026-04-29 20:18:06,116 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\proyecto-White-Houses.jpg
62
+ 2026-04-29 20:18:06,272 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.712s at 2026-04-30T02:18:06.272748+00:00
63
+ 2026-04-29 20:18:11,868 INFO backend.segmentation: [UPLOAD_BG] START at 2026-04-30T02:18:11.868080+00:00
64
+ 2026-04-29 20:18:11,868 INFO backend.segmentation: [JOB 6897b1b65f7c4201ab0a5c35bf18b368] preparing_image progress=12
65
+ 2026-04-29 20:18:11,941 INFO backend.segmentation: [JOB 6897b1b65f7c4201ab0a5c35bf18b368] segmenting_with_sam2 progress=30 estimated_seconds=49.28768
66
+ 2026-04-29 20:18:14,341 INFO httpx: HTTP Request: GET http://localhost:7860/config "HTTP/1.1 200 OK"
67
+ 2026-04-29 20:18:16,543 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/info?serialize=False "HTTP/1.1 200 OK"
68
+ 2026-04-29 20:18:16,695 INFO httpx: HTTP Request: HEAD https://huggingface.co/api/telemetry/py_client/initiated "HTTP/1.1 200 OK"
69
+ 2026-04-29 20:18:18,825 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/heartbeat/e332d34b-376c-4071-9631-656973e262a0 "HTTP/1.1 200 OK"
70
+ 2026-04-29 20:18:18,828 INFO httpx: HTTP Request: POST http://localhost:7860/gradio_api/upload "HTTP/1.1 200 OK"
71
+ 2026-04-29 20:18:21,032 INFO httpx: HTTP Request: POST http://localhost:7860/gradio_api/queue/join "HTTP/1.1 200 OK"
72
+ 2026-04-29 20:18:23,304 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/queue/data?session_hash=e332d34b-376c-4071-9631-656973e262a0 "HTTP/1.1 200 OK"
73
+ 2026-04-29 20:18:36,010 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/file=C:\Users\alane\AppData\Local\Temp\gradio\7b5a7a453887652d3284bb9eabe628e95982e15d5e0f16ff718d22beb5ed2a72\image.webp "HTTP/1.1 200 OK"
74
+ 2026-04-29 20:18:36,020 INFO services.gradio_client_service: Gradio Space segmentation: entorno=🛁 Baño / Cocina motor=SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1 mask_count=18
75
+ 2026-04-29 20:18:36,021 INFO backend.segmentation: [JOB 6897b1b65f7c4201ab0a5c35bf18b368] saving_masks progress=92
76
+ 2026-04-29 20:18:36,063 INFO backend.segmentation: [JOB 6897b1b65f7c4201ab0a5c35bf18b368] segments_meta saved (14 segments)
77
+ 2026-04-29 20:18:36,063 INFO backend.segmentation: [JOB 6897b1b65f7c4201ab0a5c35bf18b368] done mask_count=18
78
+ 2026-04-29 20:18:36,063 INFO backend.segmentation: [UPLOAD_BG] DONE 24.195s at 2026-04-30T02:18:36.063054+00:00
79
+ 2026-04-29 20:18:36,063 INFO backend.segmentation: Releasing resources (full_unload=False)
80
+ 2026-04-29 20:18:44,885 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:18:44.885155+00:00
81
+ 2026-04-29 20:18:45,431 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
82
+ 2026-04-29 20:18:45,591 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.706s at 2026-04-30T02:18:45.591016+00:00
83
+ 2026-04-29 20:18:49,898 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:18:49.898853+00:00
84
+ 2026-04-29 20:18:50,427 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
85
+ 2026-04-29 20:18:50,573 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.674s at 2026-04-30T02:18:50.573101+00:00
86
+ 2026-04-29 20:18:52,643 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:18:52.643494+00:00
87
+ 2026-04-29 20:18:53,101 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
88
+ 2026-04-29 20:18:53,259 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.615s at 2026-04-30T02:18:53.259095+00:00
89
+ 2026-04-29 20:18:55,884 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:18:55.884791+00:00
90
+ 2026-04-29 20:18:56,336 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
91
+ 2026-04-29 20:18:56,483 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.599s at 2026-04-30T02:18:56.483159+00:00
92
+ 2026-04-29 20:18:58,689 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:18:58.689702+00:00
93
+ 2026-04-29 20:18:59,139 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
94
+ 2026-04-29 20:18:59,285 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.596s at 2026-04-30T02:18:59.285688+00:00
95
+ 2026-04-29 20:19:01,587 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:19:01.587113+00:00
96
+ 2026-04-29 20:19:02,057 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
97
+ 2026-04-29 20:19:02,202 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.616s at 2026-04-30T02:19:02.202912+00:00
98
+ 2026-04-29 20:19:08,881 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:19:08.881813+00:00
99
+ 2026-04-29 20:19:09,450 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
100
+ 2026-04-29 20:19:09,598 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.716s at 2026-04-30T02:19:09.598660+00:00
101
+ 2026-04-29 20:19:14,081 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:19:14.081047+00:00
102
+ 2026-04-29 20:19:14,613 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
103
+ 2026-04-29 20:19:14,765 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.684s at 2026-04-30T02:19:14.765513+00:00
104
+ 2026-04-29 20:19:20,588 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:19:20.588691+00:00
105
+ 2026-04-29 20:19:21,001 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
106
+ 2026-04-29 20:19:21,148 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.560s at 2026-04-30T02:19:21.148963+00:00
107
+ 2026-04-29 20:19:26,717 INFO backend.segmentation: [UPLOAD_BG] START at 2026-04-30T02:19:26.717015+00:00
108
+ 2026-04-29 20:19:26,717 INFO backend.segmentation: [JOB 0e77f0bbab294a828b0dbfbb826c3805] preparing_image progress=12
109
+ 2026-04-29 20:19:26,784 INFO backend.segmentation: [JOB 0e77f0bbab294a828b0dbfbb826c3805] segmenting_with_sam2 progress=30 estimated_seconds=49.28768
110
+ 2026-04-29 20:19:29,222 INFO httpx: HTTP Request: GET http://localhost:7860/config "HTTP/1.1 200 OK"
111
+ 2026-04-29 20:19:31,597 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/info?serialize=False "HTTP/1.1 200 OK"
112
+ 2026-04-29 20:19:31,734 INFO httpx: HTTP Request: HEAD https://huggingface.co/api/telemetry/py_client/initiated "HTTP/1.1 200 OK"
113
+ 2026-04-29 20:19:34,073 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/heartbeat/19c5143b-64ec-4b5d-942b-098f7096a07d "HTTP/1.1 200 OK"
114
+ 2026-04-29 20:19:34,076 INFO httpx: HTTP Request: POST http://localhost:7860/gradio_api/upload "HTTP/1.1 200 OK"
115
+ 2026-04-29 20:19:36,338 INFO httpx: HTTP Request: POST http://localhost:7860/gradio_api/queue/join "HTTP/1.1 200 OK"
116
+ 2026-04-29 20:19:38,618 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/queue/data?session_hash=19c5143b-64ec-4b5d-942b-098f7096a07d "HTTP/1.1 200 OK"
117
+ 2026-04-29 20:19:50,817 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/file=C:\Users\alane\AppData\Local\Temp\gradio\627367a96ce0d7cea77d51e3b57be3a803ddd9b06e2c8a9547129f322756dd05\image.webp "HTTP/1.1 200 OK"
118
+ 2026-04-29 20:19:50,828 INFO services.gradio_client_service: Gradio Space segmentation: entorno=🛁 Baño / Cocina motor=SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1 mask_count=13
119
+ 2026-04-29 20:19:50,828 INFO backend.segmentation: [JOB 0e77f0bbab294a828b0dbfbb826c3805] saving_masks progress=92
120
+ 2026-04-29 20:19:50,860 INFO backend.segmentation: [JOB 0e77f0bbab294a828b0dbfbb826c3805] segments_meta saved (13 segments)
121
+ 2026-04-29 20:19:50,861 INFO backend.segmentation: [JOB 0e77f0bbab294a828b0dbfbb826c3805] done mask_count=13
122
+ 2026-04-29 20:19:50,861 INFO backend.segmentation: [UPLOAD_BG] DONE 24.145s at 2026-04-30T02:19:50.861597+00:00
123
+ 2026-04-29 20:19:50,861 INFO backend.segmentation: Releasing resources (full_unload=False)
124
+ 2026-04-29 20:19:58,632 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:19:58.632422+00:00
125
+ 2026-04-29 20:19:58,950 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
126
+ 2026-04-29 20:19:59,096 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.464s at 2026-04-30T02:19:59.096073+00:00
127
+ 2026-04-29 20:20:03,025 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:20:03.025850+00:00
128
+ 2026-04-29 20:20:03,491 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
129
+ 2026-04-29 20:20:03,640 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.615s at 2026-04-30T02:20:03.640105+00:00
130
+ 2026-04-29 20:20:20,501 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:20:20.501928+00:00
131
+ 2026-04-29 20:20:21,076 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
132
+ 2026-04-29 20:20:21,227 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.727s at 2026-04-30T02:20:21.227737+00:00
133
+ 2026-04-29 20:20:28,266 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:20:28.266563+00:00
134
+ 2026-04-29 20:20:28,768 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
135
+ 2026-04-29 20:20:28,935 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.669s at 2026-04-30T02:20:28.935807+00:00
136
+ 2026-04-29 20:20:35,728 INFO backend.segmentation: [UPLOAD_BG] START at 2026-04-30T02:20:35.728058+00:00
137
+ 2026-04-29 20:20:35,729 INFO backend.segmentation: [JOB f44cfa950b0546ffbcd7fa090bad49db] preparing_image progress=12
138
+ 2026-04-29 20:20:35,790 INFO backend.segmentation: [JOB f44cfa950b0546ffbcd7fa090bad49db] segmenting_with_sam2 progress=30 estimated_seconds=49.28768
139
+ 2026-04-29 20:20:38,252 INFO httpx: HTTP Request: GET http://localhost:7860/config "HTTP/1.1 200 OK"
140
+ 2026-04-29 20:20:40,610 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/info?serialize=False "HTTP/1.1 200 OK"
141
+ 2026-04-29 20:20:40,810 INFO httpx: HTTP Request: HEAD https://huggingface.co/api/telemetry/py_client/initiated "HTTP/1.1 200 OK"
142
+ 2026-04-29 20:20:43,106 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/heartbeat/31bdf8c4-3e85-4561-b055-cb540bff6222 "HTTP/1.1 200 OK"
143
+ 2026-04-29 20:20:43,110 INFO httpx: HTTP Request: POST http://localhost:7860/gradio_api/upload "HTTP/1.1 200 OK"
144
+ 2026-04-29 20:20:45,435 INFO httpx: HTTP Request: POST http://localhost:7860/gradio_api/queue/join "HTTP/1.1 200 OK"
145
+ 2026-04-29 20:20:47,968 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/queue/data?session_hash=31bdf8c4-3e85-4561-b055-cb540bff6222 "HTTP/1.1 200 OK"
146
+ 2026-04-29 20:21:09,199 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/file=C:\Users\alane\AppData\Local\Temp\gradio\de39b2da096587a3b0e0d7fb57541b12755192b377f4914a8047c40356bfbf4a\image.webp "HTTP/1.1 200 OK"
147
+ 2026-04-29 20:21:09,216 INFO services.gradio_client_service: Gradio Space segmentation: entorno=🛁 Baño / Cocina motor=SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1 mask_count=30
148
+ 2026-04-29 20:21:09,217 INFO backend.segmentation: [JOB f44cfa950b0546ffbcd7fa090bad49db] saving_masks progress=92
149
+ 2026-04-29 20:21:09,330 INFO backend.segmentation: [JOB f44cfa950b0546ffbcd7fa090bad49db] segments_meta saved (18 segments)
150
+ 2026-04-29 20:21:09,330 INFO backend.segmentation: [JOB f44cfa950b0546ffbcd7fa090bad49db] done mask_count=30
151
+ 2026-04-29 20:21:09,331 INFO backend.segmentation: [UPLOAD_BG] DONE 33.603s at 2026-04-30T02:21:09.331315+00:00
152
+ 2026-04-29 20:21:09,331 INFO backend.segmentation: Releasing resources (full_unload=False)
153
+ 2026-04-29 20:21:19,563 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:21:19.563482+00:00
154
+ 2026-04-29 20:21:19,875 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
155
+ 2026-04-29 20:21:20,037 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.474s at 2026-04-30T02:21:20.037544+00:00
156
+ 2026-04-29 20:21:27,716 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:21:27.716717+00:00
157
+ 2026-04-29 20:21:28,240 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
158
+ 2026-04-29 20:21:28,388 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.671s at 2026-04-30T02:21:28.388007+00:00
159
+ 2026-04-29 20:21:33,770 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:21:33.770053+00:00
160
+ 2026-04-29 20:21:34,297 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
161
+ 2026-04-29 20:21:34,445 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.676s at 2026-04-30T02:21:34.445668+00:00
162
+ 2026-04-29 20:21:45,556 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:21:45.556315+00:00
163
+ 2026-04-29 20:21:46,063 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
164
+ 2026-04-29 20:21:46,214 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.658s at 2026-04-30T02:21:46.214366+00:00
165
+ 2026-04-29 20:21:54,885 INFO backend.segmentation: [UPLOAD_BG] START at 2026-04-30T02:21:54.885450+00:00
166
+ 2026-04-29 20:21:54,886 INFO backend.segmentation: [JOB ec618977b0b7478ca5d30d251fa15945] preparing_image progress=12
167
+ 2026-04-29 20:21:55,003 INFO backend.segmentation: [JOB ec618977b0b7478ca5d30d251fa15945] segmenting_with_sam2 progress=30 estimated_seconds=138.4576
168
+ 2026-04-29 20:21:57,389 INFO httpx: HTTP Request: GET http://localhost:7860/config "HTTP/1.1 200 OK"
169
+ 2026-04-29 20:21:59,757 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/info?serialize=False "HTTP/1.1 200 OK"
170
+ 2026-04-29 20:21:59,891 INFO httpx: HTTP Request: HEAD https://huggingface.co/api/telemetry/py_client/initiated "HTTP/1.1 200 OK"
171
+ 2026-04-29 20:22:02,312 INFO httpx: HTTP Request: POST http://localhost:7860/gradio_api/upload "HTTP/1.1 200 OK"
172
+ 2026-04-29 20:22:02,322 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/heartbeat/3f8ed7a1-4b28-46c2-9e01-7e4358b38e76 "HTTP/1.1 200 OK"
173
+ 2026-04-29 20:22:04,682 INFO httpx: HTTP Request: POST http://localhost:7860/gradio_api/queue/join "HTTP/1.1 200 OK"
174
+ 2026-04-29 20:22:07,179 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/queue/data?session_hash=3f8ed7a1-4b28-46c2-9e01-7e4358b38e76 "HTTP/1.1 200 OK"
175
+ 2026-04-29 20:22:33,186 INFO httpx: HTTP Request: GET http://localhost:7860/gradio_api/file=C:\Users\alane\AppData\Local\Temp\gradio\80421cbcd599451a04044e3ece45f375843574c97db6199cd4e3f022f90b9311\image.webp "HTTP/1.1 200 OK"
176
+ 2026-04-29 20:22:33,213 INFO services.gradio_client_service: Gradio Space segmentation: entorno=🛁 Baño / Cocina motor=SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1 mask_count=16
177
+ 2026-04-29 20:22:33,214 INFO backend.segmentation: [JOB ec618977b0b7478ca5d30d251fa15945] saving_masks progress=92
178
+ 2026-04-29 20:22:33,419 INFO backend.segmentation: [JOB ec618977b0b7478ca5d30d251fa15945] segments_meta saved (16 segments)
179
+ 2026-04-29 20:22:33,419 INFO backend.segmentation: [JOB ec618977b0b7478ca5d30d251fa15945] done mask_count=16
180
+ 2026-04-29 20:22:33,419 INFO backend.segmentation: [UPLOAD_BG] DONE 38.534s at 2026-04-30T02:22:33.419503+00:00
181
+ 2026-04-29 20:22:33,420 INFO backend.segmentation: Releasing resources (full_unload=False)
182
+ 2026-04-29 20:22:38,594 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:22:38.593824+00:00
183
+ 2026-04-29 20:22:38,977 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
184
+ 2026-04-29 20:22:39,402 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.808s at 2026-04-30T02:22:39.402689+00:00
185
+ 2026-04-29 20:22:44,189 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:22:44.189800+00:00
186
+ 2026-04-29 20:22:44,726 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
187
+ 2026-04-29 20:22:45,179 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.990s at 2026-04-30T02:22:45.179303+00:00
188
+ 2026-04-29 20:22:50,087 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:22:50.087424+00:00
189
+ 2026-04-29 20:22:50,751 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\demo-room.jpg
190
+ 2026-04-29 20:22:51,466 INFO backend.segmentation: [APPLY_TEXTURE] DONE 1.379s at 2026-04-30T02:22:51.466435+00:00
191
+ 2026-04-29 20:26:39,065 INFO backend.segmentation: [LIFESPAN] GRADIO_SPACE_URL set — skipping local SAM2 load.
192
+ 2026-04-29 20:26:39,964 INFO backend.segmentation: [LIFESPAN] GRADIO_SPACE_URL set — skipping local SAM2 load.
193
+ 2026-04-29 20:33:56,025 INFO backend.segmentation: [LIFESPAN] GRADIO_SPACE_URL set — skipping local SAM2 load.
194
+ 2026-04-29 20:34:02,828 INFO backend.segmentation: [UPLOAD_BG] START at 2026-04-30T02:34:02.828129+00:00
195
+ 2026-04-29 20:34:02,830 INFO backend.segmentation: [JOB ccecb5fbdf744d9eae57eb2b04e0af13] preparing_image progress=12
196
+ 2026-04-29 20:34:02,900 INFO backend.segmentation: [JOB ccecb5fbdf744d9eae57eb2b04e0af13] segmenting_with_sam2 progress=30 estimated_seconds=51.939840000000004
197
+ 2026-04-29 20:34:04,067 INFO httpx: HTTP Request: GET https://eduardo4547-hyper-reality-sam2-gpu.hf.space/config "HTTP/1.1 200 OK"
198
+ 2026-04-29 20:34:04,727 INFO httpx: HTTP Request: GET https://eduardo4547-hyper-reality-sam2-gpu.hf.space/gradio_api/info?serialize=False "HTTP/1.1 200 OK"
199
+ 2026-04-29 20:34:05,153 INFO httpx: HTTP Request: HEAD https://huggingface.co/api/telemetry/py_client/initiated "HTTP/1.1 200 OK"
200
+ 2026-04-29 20:34:05,258 INFO httpx: HTTP Request: GET https://eduardo4547-hyper-reality-sam2-gpu.hf.space/gradio_api/heartbeat/b306737b-bf28-4f02-8963-83b74032d449 "HTTP/1.1 200 OK"
201
+ 2026-04-29 20:34:05,354 INFO httpx: HTTP Request: POST https://eduardo4547-hyper-reality-sam2-gpu.hf.space/gradio_api/upload "HTTP/1.1 200 OK"
202
+ 2026-04-29 20:34:05,788 INFO httpx: HTTP Request: POST https://eduardo4547-hyper-reality-sam2-gpu.hf.space/gradio_api/queue/join "HTTP/1.1 200 OK"
203
+ 2026-04-29 20:34:06,344 INFO httpx: HTTP Request: GET https://eduardo4547-hyper-reality-sam2-gpu.hf.space/gradio_api/queue/data?session_hash=b306737b-bf28-4f02-8963-83b74032d449 "HTTP/1.1 200 OK"
204
+ 2026-04-29 20:34:24,624 INFO httpx: HTTP Request: GET https://eduardo4547-hyper-reality-sam2-gpu.hf.space/gradio_api/file=/tmp/gradio/edcd82066c73a2359a9133192b4091c873fb9fca768c0f377a7a519aeb9f9b3a/image.webp "HTTP/1.1 200 OK"
205
+ 2026-04-29 20:34:24,678 INFO services.gradio_client_service: Gradio Space segmentation: entorno=🌳 Terraza / Patio / Jardín motor=Híbrido Arquitectura (Cityscapes Grande + DINO Pequeño) mask_count=20
206
+ 2026-04-29 20:34:24,684 INFO backend.segmentation: [JOB ccecb5fbdf744d9eae57eb2b04e0af13] saving_masks progress=92
207
+ 2026-04-29 20:34:24,781 INFO backend.segmentation: [JOB ccecb5fbdf744d9eae57eb2b04e0af13] segments_meta saved (20 segments)
208
+ 2026-04-29 20:34:24,782 INFO backend.segmentation: [JOB ccecb5fbdf744d9eae57eb2b04e0af13] done mask_count=20
209
+ 2026-04-29 20:34:24,782 INFO backend.segmentation: [UPLOAD_BG] DONE 21.955s at 2026-04-30T02:34:24.782746+00:00
210
+ 2026-04-29 20:34:24,783 INFO backend.segmentation: Releasing resources (full_unload=False)
211
+ 2026-04-29 20:34:27,987 INFO backend.segmentation: [APPLY_TEXTURE] START at 2026-04-30T02:34:27.987941+00:00
212
+ 2026-04-29 20:34:28,292 INFO backend.segmentation: [APPLY_TEXTURE] cleared mask from original source: C:\Users\alane\OneDrive\Escritorio\Trabajo\Prueba-PoC\backend\uploads\proyecto-White-Houses.jpg
213
+ 2026-04-29 20:34:28,570 INFO backend.segmentation: [APPLY_TEXTURE] DONE 0.582s at 2026-04-30T02:34:28.570140+00:00
backend/requirements.txt CHANGED
@@ -1,15 +1,11 @@
1
- fastapi==0.111.1
2
- python-dotenv
3
- uvicorn[standard]==0.23.2
4
- motor==3.4.0
5
- pymongo==4.7.2
6
- transformers==4.36.2
7
- numpy
8
- Pillow
9
- pydantic
10
- hydra-core
11
- omegaconf
12
- git+https://github.com/facebookresearch/sam2.git
13
- python-multipart
14
- torch
15
- opencv-python-headless
 
1
+ fastapi==0.111.1
2
+ python-dotenv
3
+ uvicorn[standard]==0.23.2
4
+ motor==3.4.0
5
+ pymongo==4.7.2
6
+ numpy
7
+ Pillow
8
+ pydantic
9
+ python-multipart
10
+ gradio_client
11
+ opencv-python-headless
 
 
 
 
backend/routers/__pycache__/auth.cpython-312.pyc CHANGED
Binary files a/backend/routers/__pycache__/auth.cpython-312.pyc and b/backend/routers/__pycache__/auth.cpython-312.pyc differ
 
backend/routers/__pycache__/catalog.cpython-312.pyc CHANGED
Binary files a/backend/routers/__pycache__/catalog.cpython-312.pyc and b/backend/routers/__pycache__/catalog.cpython-312.pyc differ
 
backend/routers/__pycache__/pages.cpython-312.pyc CHANGED
Binary files a/backend/routers/__pycache__/pages.cpython-312.pyc and b/backend/routers/__pycache__/pages.cpython-312.pyc differ
 
backend/routers/__pycache__/segmentation.cpython-312.pyc CHANGED
Binary files a/backend/routers/__pycache__/segmentation.cpython-312.pyc and b/backend/routers/__pycache__/segmentation.cpython-312.pyc differ
 
backend/routers/catalog.py CHANGED
@@ -123,132 +123,6 @@ _CATALOG = [
123
  },
124
  ],
125
  },
126
- {
127
- "id": "pisos",
128
- "nombre": "Pisos",
129
- "descripcion": "Pisos de madera, laminado y mármol",
130
- "productos": [
131
- {
132
- "id": "piso_madera",
133
- "nombre": "Madera Natural",
134
- "textura": "wood_floor_diff_2k.jpg",
135
- "url_preview": "/seg/texture-preview/wood_floor_diff_2k.jpg",
136
- "dimensiones": [],
137
- },
138
- {
139
- "id": "piso_tablones",
140
- "nombre": "Tablones de Madera",
141
- "textura": "wood_planks_diff_2k.jpg",
142
- "url_preview": "/seg/texture-preview/wood_planks_diff_2k.jpg",
143
- "dimensiones": [],
144
- },
145
- {
146
- "id": "piso_laminado",
147
- "nombre": "Laminado",
148
- "textura": "laminate_floor_02_diff_2k.jpg",
149
- "url_preview": "/seg/texture-preview/laminate_floor_02_diff_2k.jpg",
150
- "dimensiones": [],
151
- },
152
- {
153
- "id": "piso_duela",
154
- "nombre": "Duela",
155
- "textura": "plank_flooring_04_diff_2k.jpg",
156
- "url_preview": "/seg/texture-preview/plank_flooring_04_diff_2k.jpg",
157
- "dimensiones": [],
158
- },
159
- {
160
- "id": "piso_marmol",
161
- "nombre": "Mármol",
162
- "textura": "marble_01_diff_2k.jpg",
163
- "url_preview": "/seg/texture-preview/marble_01_diff_2k.jpg",
164
- "dimensiones": [],
165
- },
166
- ],
167
- },
168
- {
169
- "id": "piedra_concreto",
170
- "nombre": "Piedra y Concreto",
171
- "descripcion": "Materiales de piedra, adoquín y granito",
172
- "productos": [
173
- {
174
- "id": "piedra_ladrillo",
175
- "nombre": "Ladrillo / Pavimento",
176
- "textura": "brick_pavement_03_diff_2k.jpg",
177
- "url_preview": "/seg/texture-preview/brick_pavement_03_diff_2k.jpg",
178
- "dimensiones": [],
179
- },
180
- {
181
- "id": "piedra_adoquin",
182
- "nombre": "Adoquín",
183
- "textura": "cobblestone_floor_08_diff_2k.jpg",
184
- "url_preview": "/seg/texture-preview/cobblestone_floor_08_diff_2k.jpg",
185
- "dimensiones": [],
186
- },
187
- {
188
- "id": "piedra_roca",
189
- "nombre": "Roca Natural",
190
- "textura": "dry_riverbed_rock_diff_2k.jpg",
191
- "url_preview": "/seg/texture-preview/dry_riverbed_rock_diff_2k.jpg",
192
- "dimensiones": [],
193
- },
194
- {
195
- "id": "piedra_granito",
196
- "nombre": "Granito",
197
- "textura": "granite_tile_diff_2k.jpg",
198
- "url_preview": "/seg/texture-preview/granite_tile_diff_2k.jpg",
199
- "dimensiones": [],
200
- },
201
- {
202
- "id": "piedra_cartago",
203
- "nombre": "Cartago Gris",
204
- "textura": "grey_cartago_03_diff_2k.jpg",
205
- "url_preview": "/seg/texture-preview/grey_cartago_03_diff_2k.jpg",
206
- "dimensiones": [],
207
- },
208
- ],
209
- },
210
- {
211
- "id": "metales",
212
- "nombre": "Metales",
213
- "descripcion": "Acabados metálicos y estructurales",
214
- "productos": [
215
- {
216
- "id": "metal_azul",
217
- "nombre": "Metal Azul",
218
- "textura": "blue_metal_plate_diff_2k.jpg",
219
- "url_preview": "/seg/texture-preview/blue_metal_plate_diff_2k.jpg",
220
- "dimensiones": [],
221
- },
222
- {
223
- "id": "metal_placa",
224
- "nombre": "Placa Metálica",
225
- "textura": "metal_plate_diff_2k.jpg",
226
- "url_preview": "/seg/texture-preview/metal_plate_diff_2k.jpg",
227
- "dimensiones": [],
228
- },
229
- {
230
- "id": "metal_oxido",
231
- "nombre": "Metal Oxidado",
232
- "textura": "rusty_metal_grid_diff_2k.jpg",
233
- "url_preview": "/seg/texture-preview/rusty_metal_grid_diff_2k.jpg",
234
- "dimensiones": [],
235
- },
236
- ],
237
- },
238
- {
239
- "id": "madera",
240
- "nombre": "Madera",
241
- "descripcion": "Acabados en madera para interiores",
242
- "productos": [
243
- {
244
- "id": "madera_gabinete",
245
- "nombre": "Gabinete de Madera",
246
- "textura": "wood_cabinet_worn_long_diff_2k.jpg",
247
- "url_preview": "/seg/texture-preview/wood_cabinet_worn_long_diff_2k.jpg",
248
- "dimensiones": [],
249
- },
250
- ],
251
- },
252
  ]
253
 
254
 
 
123
  },
124
  ],
125
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  ]
127
 
128
 
backend/services/__pycache__/gradio_client_service.cpython-312.pyc ADDED
Binary file (4.34 kB). View file
 
backend/services/__pycache__/image_service.cpython-312.pyc CHANGED
Binary files a/backend/services/__pycache__/image_service.cpython-312.pyc and b/backend/services/__pycache__/image_service.cpython-312.pyc differ
 
backend/services/__pycache__/sam2_service.cpython-312.pyc CHANGED
Binary files a/backend/services/__pycache__/sam2_service.cpython-312.pyc and b/backend/services/__pycache__/sam2_service.cpython-312.pyc differ
 
backend/services/__pycache__/scene_service.cpython-312.pyc CHANGED
Binary files a/backend/services/__pycache__/scene_service.cpython-312.pyc and b/backend/services/__pycache__/scene_service.cpython-312.pyc differ
 
backend/services/__pycache__/segmentation_service.cpython-312.pyc CHANGED
Binary files a/backend/services/__pycache__/segmentation_service.cpython-312.pyc and b/backend/services/__pycache__/segmentation_service.cpython-312.pyc differ
 
backend/services/__pycache__/texture_service.cpython-312.pyc CHANGED
Binary files a/backend/services/__pycache__/texture_service.cpython-312.pyc and b/backend/services/__pycache__/texture_service.cpython-312.pyc differ
 
backend/services/gradio_client_service.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Cliente para llamar al Gradio Space de ZeroGPU (SAM2 + SegFormer + DINO).
3
+ Se activa solo si GRADIO_SPACE_URL está definido en el entorno.
4
+ """
5
+ import asyncio
6
+ import base64
7
+ import io
8
+ import json
9
+ import logging
10
+ from pathlib import Path
11
+
12
+ import numpy as np
13
+ from PIL import Image
14
+
15
+ from core.config import GRADIO_SPACE_URL
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ def is_gradio_enabled() -> bool:
21
+ return bool(GRADIO_SPACE_URL)
22
+
23
+
24
+ def _call_gradio_sync(image_path: Path) -> tuple[np.ndarray, int]:
25
+ """
26
+ Synchronous Gradio call — safe to invoke from a background thread.
27
+ Returns (label_map, mask_count).
28
+ Raises on any error so the caller can handle fallback.
29
+ """
30
+ from gradio_client import Client, file # type: ignore
31
+
32
+ client = Client(GRADIO_SPACE_URL)
33
+
34
+ # segment_for_backend returns (overlay_image, combined_json_str)
35
+ _overlay_file, combined_json_str = client.predict(
36
+ file(str(image_path)),
37
+ api_name="/segment",
38
+ )
39
+
40
+ if not isinstance(combined_json_str, str):
41
+ raise ValueError(f"Unexpected response type from Gradio Space: {type(combined_json_str)}")
42
+
43
+ combined: dict = json.loads(combined_json_str)
44
+
45
+ if "error" in combined:
46
+ raise RuntimeError(f"Gradio Space error: {combined['error'][:500]}")
47
+
48
+ label_map_b64: str = combined.get("label_map_b64", "")
49
+ if not label_map_b64:
50
+ return np.zeros((1, 1), dtype=np.uint8), 0
51
+
52
+ # Decode PNG-encoded label map (lossless uint8 grayscale)
53
+ label_map_bytes = base64.b64decode(label_map_b64)
54
+ pil_label = Image.open(io.BytesIO(label_map_bytes))
55
+ label_map = np.array(pil_label, dtype=np.uint8)
56
+ mask_count = int(label_map.max())
57
+
58
+ entorno = combined.get("entorno", "?")
59
+ motor = combined.get("motor", "?")
60
+ logger.info(
61
+ "Gradio Space segmentation: entorno=%s motor=%s mask_count=%d",
62
+ entorno, motor, mask_count,
63
+ )
64
+
65
+ return label_map, mask_count
66
+
67
+
68
+ def segment_via_gradio_sync(image_path: Path) -> tuple[np.ndarray, int] | None:
69
+ """
70
+ Blocking call to the Gradio Space from a sync context (background task thread).
71
+ Returns (label_map, mask_count) or None on failure / not configured.
72
+ """
73
+ if not is_gradio_enabled():
74
+ return None
75
+ try:
76
+ return _call_gradio_sync(image_path)
77
+ except Exception as exc:
78
+ logger.warning("Gradio Space call failed, falling back to local SAM2: %s", exc)
79
+ return None
80
+
81
+
82
+ async def segment_via_gradio(image_path: Path) -> tuple[np.ndarray, int] | None:
83
+ """
84
+ Async wrapper — offloads the blocking Gradio call to a thread.
85
+ Returns (label_map, mask_count) or None on failure / not configured.
86
+ """
87
+ if not is_gradio_enabled():
88
+ return None
89
+ try:
90
+ return await asyncio.to_thread(_call_gradio_sync, image_path)
91
+ except Exception as exc:
92
+ logger.warning("Gradio Space call failed: %s", exc)
93
+ return None
backend/services/image_service.py CHANGED
@@ -18,6 +18,7 @@ from core.config import (
18
  logger,
19
  utc_now_iso,
20
  )
 
21
  from services.sam2_service import (
22
  jobs,
23
  jobs_lock,
@@ -131,8 +132,17 @@ def run_upload_job(job_id: str, content: bytes, original_name: str) -> None:
131
  })
132
  logger.info(f"[JOB {job_id}] segmenting_with_sam2 progress=30 estimated_seconds={estimated_seconds}")
133
 
134
- generate_label_map = _get_generate_label_map()
135
- label_map, mask_count = generate_label_map(image_rgb)
 
 
 
 
 
 
 
 
 
136
 
137
  with jobs_lock:
138
  job = jobs.setdefault(job_id, {})
 
18
  logger,
19
  utc_now_iso,
20
  )
21
+ from services.gradio_client_service import is_gradio_enabled, segment_via_gradio_sync
22
  from services.sam2_service import (
23
  jobs,
24
  jobs_lock,
 
132
  })
133
  logger.info(f"[JOB {job_id}] segmenting_with_sam2 progress=30 estimated_seconds={estimated_seconds}")
134
 
135
+ image_path = UPLOAD_DIR / safe_name
136
+ if is_gradio_enabled():
137
+ gradio_result = segment_via_gradio_sync(image_path)
138
+ else:
139
+ gradio_result = None
140
+
141
+ if gradio_result is not None:
142
+ label_map, mask_count = gradio_result
143
+ else:
144
+ generate_label_map = _get_generate_label_map()
145
+ label_map, mask_count = generate_label_map(image_rgb)
146
 
147
  with jobs_lock:
148
  job = jobs.setdefault(job_id, {})
backend/services/sam2_service.py CHANGED
@@ -6,7 +6,13 @@ from contextlib import asynccontextmanager
6
  from pathlib import Path
7
  from typing import Any
8
 
9
- import torch
 
 
 
 
 
 
10
  from fastapi import FastAPI, HTTPException
11
 
12
  from core.config import (
@@ -107,6 +113,11 @@ def find_sam2_model_path() -> Path:
107
  def load_sam2_model() -> None:
108
  global sam2_mask_generator, sam2_image_predictor, sam2_load_error
109
 
 
 
 
 
 
110
  if not _SAM2_AVAILABLE:
111
  sam2_load_error = "SAM2 library not installed"
112
  logger.error(f"[SAM2] ERROR: {sam2_load_error}")
@@ -226,29 +237,30 @@ def release_resources(full_unload: bool = False) -> None:
226
  sam2_image_predictor = None
227
  sam2_load_error = None
228
 
229
- try:
230
- if torch.cuda.is_available():
231
- try:
232
- torch.cuda.synchronize()
233
- except Exception:
234
- pass
235
- try:
236
- torch.cuda.empty_cache()
237
- except Exception:
238
- pass
239
- try:
240
- if hasattr(torch.cuda, "ipc_collect"):
241
- torch.cuda.ipc_collect()
242
- except Exception:
243
- pass
244
- try:
245
- reserved = torch.cuda.memory_reserved()
246
- allocated = torch.cuda.memory_allocated()
247
- logger.info(f"CUDA memory reserved={reserved} allocated={allocated}")
248
- except Exception:
249
- pass
250
- except Exception:
251
- pass
 
252
 
253
  gc.collect()
254
  except Exception as exc:
@@ -258,6 +270,11 @@ def release_resources(full_unload: bool = False) -> None:
258
  @asynccontextmanager
259
  async def lifespan(app: FastAPI) -> AsyncIterator[None]:
260
  import asyncio
 
 
 
 
 
261
  try:
262
  load_sam2_model()
263
  yield
 
6
  from pathlib import Path
7
  from typing import Any
8
 
9
+ try:
10
+ import torch
11
+ _TORCH_AVAILABLE = True
12
+ except ImportError:
13
+ torch = None # type: ignore[assignment]
14
+ _TORCH_AVAILABLE = False
15
+
16
  from fastapi import FastAPI, HTTPException
17
 
18
  from core.config import (
 
113
  def load_sam2_model() -> None:
114
  global sam2_mask_generator, sam2_image_predictor, sam2_load_error
115
 
116
+ if not _TORCH_AVAILABLE:
117
+ sam2_load_error = "torch not installed — SAM2 unavailable (using Gradio Space)"
118
+ logger.warning(f"[SAM2] {sam2_load_error}")
119
+ return
120
+
121
  if not _SAM2_AVAILABLE:
122
  sam2_load_error = "SAM2 library not installed"
123
  logger.error(f"[SAM2] ERROR: {sam2_load_error}")
 
237
  sam2_image_predictor = None
238
  sam2_load_error = None
239
 
240
+ if _TORCH_AVAILABLE:
241
+ try:
242
+ if torch.cuda.is_available():
243
+ try:
244
+ torch.cuda.synchronize()
245
+ except Exception:
246
+ pass
247
+ try:
248
+ torch.cuda.empty_cache()
249
+ except Exception:
250
+ pass
251
+ try:
252
+ if hasattr(torch.cuda, "ipc_collect"):
253
+ torch.cuda.ipc_collect()
254
+ except Exception:
255
+ pass
256
+ try:
257
+ reserved = torch.cuda.memory_reserved()
258
+ allocated = torch.cuda.memory_allocated()
259
+ logger.info(f"CUDA memory reserved={reserved} allocated={allocated}")
260
+ except Exception:
261
+ pass
262
+ except Exception:
263
+ pass
264
 
265
  gc.collect()
266
  except Exception as exc:
 
270
  @asynccontextmanager
271
  async def lifespan(app: FastAPI) -> AsyncIterator[None]:
272
  import asyncio
273
+ from services.gradio_client_service import is_gradio_enabled
274
+ if is_gradio_enabled():
275
+ logger.info("[LIFESPAN] GRADIO_SPACE_URL set — skipping local SAM2 load.")
276
+ yield
277
+ return
278
  try:
279
  load_sam2_model()
280
  yield
backend/services/segmentation_service.py CHANGED
@@ -3,7 +3,12 @@ from typing import Any, cast
3
 
4
  import cv2
5
  import numpy as np
6
- import torch
 
 
 
 
 
7
  from fastapi import HTTPException
8
  from PIL import Image
9
 
 
3
 
4
  import cv2
5
  import numpy as np
6
+ try:
7
+ import torch
8
+ _TORCH_AVAILABLE = True
9
+ except ImportError:
10
+ torch = None # type: ignore[assignment]
11
+ _TORCH_AVAILABLE = False
12
  from fastapi import HTTPException
13
  from PIL import Image
14
 
backend/uploads/demo-room.jpg ADDED

Git LFS Details

  • SHA256: 3b0bbc8d29cc450c19f13c4a6b0dd6d746d374218e041efb77180a40cdab38e4
  • Pointer size: 131 Bytes
  • Size of remote file: 200 kB
backend/uploads/demo-room_edit_007d1456.jpg ADDED
backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2.jpg ADDED
backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1.jpg ADDED
backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006.jpg ADDED
backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74.jpg ADDED
backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc.jpg ADDED
backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6.jpg ADDED
backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6_edit_78068a16.jpg ADDED
backend/uploads/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6_edit_78068a16_edit_bc375f53.jpg ADDED
backend/uploads/demo-room_edit_09a864d7.jpg ADDED
backend/uploads/demo-room_edit_09a864d7_edit_a3f60d46.jpg ADDED
backend/uploads/demo-room_edit_09a864d7_edit_a3f60d46_edit_eecc8494.jpg ADDED
backend/uploads/demo-room_edit_09a864d7_edit_a3f60d46_edit_eecc8494_edit_310aa4a1.jpg ADDED
backend/uploads/demo-room_edit_ef2b9c2c.jpg ADDED

Git LFS Details

  • SHA256: 3d11f625c970aceecca7eaf6c5cab0dc32b03ed57126cc1d2eb7de89702100b8
  • Pointer size: 131 Bytes
  • Size of remote file: 185 kB
backend/uploads/demo-room_edit_ef2b9c2c_edit_32b3c807.jpg ADDED

Git LFS Details

  • SHA256: 1cb0187dc63d5242fbe796228ef0a6fa76106ae77fedbdd17251c1d14d21ce1b
  • Pointer size: 131 Bytes
  • Size of remote file: 186 kB
backend/uploads/demo-room_edit_ef2b9c2c_edit_32b3c807_edit_e6f30d22.jpg ADDED

Git LFS Details

  • SHA256: 4915a994061321b1db2f3e70231407912c48abaa5172c1d75ffa505561c8b741
  • Pointer size: 131 Bytes
  • Size of remote file: 219 kB
backend/uploads/demo-room_edit_f6aa2f46.jpg ADDED
backend/uploads/demo-room_edit_f6aa2f46_edit_2063dc93.jpg ADDED
backend/uploads/demo-room_edit_f6aa2f46_edit_2063dc93_edit_c151acb0.jpg ADDED
backend/uploads/demo-room_edit_f6aa2f46_edit_2063dc93_edit_c151acb0_edit_fb84149e.jpg ADDED
backend/uploads/masks/demo-room.jpg_labels.png ADDED
backend/uploads/masks/demo-room.jpg_labels_meta.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"segments": [{"index": 1, "type": "object", "label": "Objeto 1", "area_ratio": 0.0007}, {"index": 2, "type": "object", "label": "Objeto 2", "area_ratio": 0.0}, {"index": 3, "type": "object", "label": "Objeto 3", "area_ratio": 0.0001}, {"index": 4, "type": "door", "label": "Puerta 1", "area_ratio": 0.0217}, {"index": 5, "type": "wall", "label": "Pared 1", "area_ratio": 0.1139}, {"index": 6, "type": "door", "label": "Puerta 2", "area_ratio": 0.0518}, {"index": 7, "type": "object", "label": "Objeto 4", "area_ratio": 0.0027}, {"index": 8, "type": "wall", "label": "Pared 2", "area_ratio": 0.0064}, {"index": 9, "type": "object", "label": "Objeto 5", "area_ratio": 0.0017}, {"index": 10, "type": "window", "label": "Ventana 1", "area_ratio": 0.0334}, {"index": 11, "type": "wall", "label": "Pared 3", "area_ratio": 0.3694}, {"index": 12, "type": "window", "label": "Ventana 2", "area_ratio": 0.0205}, {"index": 13, "type": "window", "label": "Ventana 3", "area_ratio": 0.0059}, {"index": 14, "type": "window", "label": "Ventana 4", "area_ratio": 0.0051}, {"index": 15, "type": "window", "label": "Ventana 5", "area_ratio": 0.0047}, {"index": 16, "type": "window", "label": "Ventana 6", "area_ratio": 0.0919}]}
backend/uploads/masks/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6_edit_78068a16_edit_bc375f53_labels.png ADDED
backend/uploads/masks/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6_edit_78068a16_labels.png ADDED
backend/uploads/masks/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_edit_80f923e6_labels.png ADDED
backend/uploads/masks/demo-room_edit_007d1456_edit_fd2d2fb2_edit_2595d2b1_edit_78290006_edit_c2a2eb74_edit_2c3f80fc_labels.png ADDED