Spaces:
Sleeping
Sleeping
Fixing three bugs from nnUNetv2 wrapper, such as pacing extraction: (x,y,z) → (z,y,x) to match project convention
5fcd2a4 | """ | |
| Hugging Face Spaces entry point for seg_app. | |
| This file must be at repository root for HF Spaces deployment. | |
| IMPORTANT: | |
| - No heavy imports at module level (lazy loading only) | |
| - Model loading happens on first inference, not at startup | |
| - Gradio app is created on import but models are NOT loaded | |
| """ | |
| import os | |
| import logging | |
| import sys | |
| # Fix OpenMP duplicate library error on Windows | |
| # Must be set BEFORE importing numpy/torch | |
| os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" | |
| # Configure logging before other imports | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", | |
| ) | |
| logger = logging.getLogger(__name__) | |
| # Validate Python version | |
| if sys.version_info < (3, 8): | |
| logger.error("Python 3.8+ is required") | |
| sys.exit(1) | |
| # ============================================================================= | |
| # MONKEY-PATCH: Fix Gradio schema serialization bug | |
| # Bug: gradio_client/utils.py crashes when schema has additionalProperties: true | |
| # because it tries to do `if "const" in schema` on a boolean value. | |
| # This patch adds a guard to handle boolean schemas gracefully. | |
| # ============================================================================= | |
| def _patch_gradio_schema_bug(): | |
| """Patch the buggy _json_schema_to_python_type function in gradio_client.""" | |
| try: | |
| import gradio_client.utils as client_utils | |
| # Store original function | |
| original_func = client_utils._json_schema_to_python_type | |
| def patched_json_schema_to_python_type(schema, defs=None): | |
| """Patched version that handles boolean schemas.""" | |
| # Handle boolean schema (additionalProperties: true/false) | |
| if isinstance(schema, bool): | |
| return "Any" if schema else "None" | |
| # Handle None schema | |
| if schema is None: | |
| return "Any" | |
| # Call original for normal dict schemas | |
| return original_func(schema, defs) | |
| # Apply patch | |
| client_utils._json_schema_to_python_type = patched_json_schema_to_python_type | |
| logger.info("Applied Gradio schema bug patch") | |
| except Exception as e: | |
| logger.warning(f"Could not patch Gradio schema bug: {e}") | |
| # Apply patch before any Gradio imports | |
| _patch_gradio_schema_bug() | |
| def create_demo(): | |
| """Create and configure the Gradio demo. | |
| This function is called at import time but does NOT load any models. | |
| Models are loaded lazily on first inference via the model registry. | |
| Returns: | |
| Configured Gradio Blocks application | |
| """ | |
| try: | |
| # Import settings and configure | |
| from seg_app.config.settings import ( | |
| APP_SETTINGS, | |
| configure_logging, | |
| validate_environment, | |
| is_hf_spaces, | |
| ) | |
| # Configure logging based on environment | |
| configure_logging(verbose=not is_hf_spaces()) | |
| # Validate environment (warnings only, don't fail startup) | |
| validate_environment() | |
| # Import the Gradio app (models NOT loaded yet) | |
| from seg_app.ui.gradio_app import demo | |
| logger.info("Gradio app created successfully (models will load on first use)") | |
| return demo | |
| except ImportError as e: | |
| logger.error(f"Failed to import required modules: {e}") | |
| logger.error("Please ensure all dependencies are installed: pip install -r requirements.txt") | |
| raise | |
| except Exception as e: | |
| logger.error(f"Failed to create Gradio app: {e}") | |
| raise | |
| # Create the demo at module level (required for HF Spaces) | |
| # This does NOT load models - they are lazy-loaded on first inference | |
| demo = create_demo() | |
| # Launch the app | |
| # HF Spaces runs this file directly with `python app.py` | |
| if __name__ == "__main__": | |
| import os | |
| if os.environ.get("SPACE_ID"): | |
| # Running in HF Spaces | |
| logger.info("Starting seg_app on Hugging Face Spaces...") | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False, | |
| show_api=False, | |
| ) | |
| else: | |
| # Local development | |
| logger.info("Starting seg_app in local mode...") | |
| demo.launch( | |
| server_name="127.0.0.1", | |
| server_port=7869, | |
| share=False, | |
| ) | |
| """ | |
| >> First Launch API server backend: Start the FastAPI backend with uvicorn | |
| # uvicorn seg_app.api.app:app --reload --host 127.0.0.1 --port 8000 | |
| uvicorn seg_app.backend.api:app --reload --host 127.0.0.1 --port 8000 | |
| >> Second, Start the FastAPI Frontend: | |
| cd seg_app/ui_slicer | |
| python serve_frontend.py | |
| >> Launch Gradio App for seg_app. | |
| python app.py | |
| # Terminal 1: FastAPI Backend | |
| uvicorn seg_app.backend.api:app --reload --host 127.0.0.1 --port 8000 | |
| # Terminal 2: Frontend Server | |
| cd seg_app/ui_slicer | |
| python serve_frontend.py | |
| Unified Mode (single server — recommended) | |
| One terminal, one port, serves both frontend + backend: | |
| ---------------------- | |
| cd /media/vsap/New\ Volume1/medical_webapp/seg_app | |
| conda activate facenet | |
| uvicorn seg_app.backend.api:app --host 127.0.0.1 --port 7860 | |
| Split Mode (two terminals — for development) | |
| If you ever need separate frontend/backend (e.g., for hot-reloading the frontend): | |
| Terminal 1 — Backend: | |
| ------------------------- | |
| cd /media/vsap/New\ Volume1/medical_webapp/seg_app | |
| conda activate facenet | |
| uvicorn seg_app.backend.api:app --reload --host 127.0.0.1 --port 8000 | |
| Terminal 2 — Frontend: | |
| ------------------------- | |
| cd /media/vsap/New\ Volume1/medical_webapp/seg_app/seg_app/ui_slicer | |
| conda activate facenet | |
| python serve_frontend.py | |
| ⚠️ In split mode, you'll need to temporarily revert api-client.js to use http://localhost:8000 instead of window.location.origin. | |
| You can test locally with Docker first if you want: | |
| -------------------------- | |
| docker build -t brain-seg-app . | |
| docker run -p 7860:7860 brain-seg-app | |
| # Open http://localhost:7860 | |
| For future pushes | |
| Whenever you make changes locally and want to update the Space: | |
| -------------------------------------------------------------- | |
| cd /media/vsap/New\ Volume1/medical_webapp/seg_app | |
| conda activate facenet | |
| git add -A | |
| git commit -m "your commit message" | |
| git push hf main | |
| """ |