JatsTheAIGen commited on
Commit
18dd400
Β·
1 Parent(s): 2fe635d

api endpoints for UI migration v9

Browse files
Files changed (4) hide show
  1. ENTRY_POINT_RESOLUTION.md +178 -0
  2. GRADIO_API_CONFLICT_DIAGNOSIS.md +5 -2
  3. app.py +14 -3
  4. main.py +25 -40
ENTRY_POINT_RESOLUTION.md ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Entry Point Conflict Resolution
2
+
3
+ ## Problem Resolved
4
+
5
+ **Issue**: Both `app.py` and `main.py` were attempting to launch Gradio on port 7860, causing port conflicts.
6
+
7
+ **Root Cause**:
8
+ - `app.py` has a `if __name__ == "__main__":` block that launches Gradio
9
+ - `main.py` was also trying to create and launch its own Gradio instance
10
+ - Both tried to bind to port 7860 simultaneously
11
+
12
+ ## Solution Implemented
13
+
14
+ ### Single Entry Point Architecture
15
+
16
+ **For Hugging Face Spaces Deployment:**
17
+ - `main.py` is the **only entry point** (configured in `README.md` as `app_file: main.py`)
18
+ - `main.py` imports the interface from `app.py` without triggering its launch
19
+ - `main.py` handles the launch configuration
20
+
21
+ **For Local Development/Testing:**
22
+ - `app.py` can still be run directly (`python app.py`)
23
+ - When run directly, `app.py` launches with its own configuration
24
+ - This allows developers to test the app independently
25
+
26
+ ## How It Works
27
+
28
+ ### Import Behavior in Python
29
+
30
+ When `main.py` imports from `app.py`:
31
+ ```python
32
+ from app import create_mobile_optimized_interface
33
+ ```
34
+
35
+ - βœ… All top-level code in `app.py` executes (orchestrator initialization, etc.)
36
+ - βœ… The function `create_mobile_optimized_interface()` becomes available
37
+ - ❌ The `if __name__ == "__main__":` block does **NOT** execute (because `__name__` != `"__main__"` when imported)
38
+
39
+ ### Current Structure
40
+
41
+ ```
42
+ app.py:
43
+ - Defines: create_mobile_optimized_interface() ← Returns (demo, components)
44
+ - Has: if __name__ == "__main__": launch code ← Only runs when app.py executed directly
45
+
46
+ main.py:
47
+ - Imports: create_mobile_optimized_interface() from app.py
48
+ - Calls: demo, components = create_mobile_optimized_interface()
49
+ - Launches: demo.launch() with HF Spaces configuration
50
+ ```
51
+
52
+ ## File Roles
53
+
54
+ ### `app.py`
55
+ - **Purpose**: Core application interface and logic
56
+ - **When imported**: Provides interface creation function
57
+ - **When executed directly**: Launches app for local testing
58
+ - **Launch configuration**: Local-optimized (with share link for external access when not on HF Spaces)
59
+
60
+ ### `main.py`
61
+ - **Purpose**: HF Spaces entry point
62
+ - **When executed**: Imports from app.py and launches
63
+ - **Launch configuration**: HF Spaces-optimized (detects environment, adjusts share setting)
64
+ - **HF Spaces requirement**: Must be specified as `app_file: main.py` in README.md
65
+
66
+ ## Configuration
67
+
68
+ ### Hugging Face Spaces Setup
69
+
70
+ In `README.md`:
71
+ ```yaml
72
+ sdk: gradio
73
+ app_file: main.py # ← This tells HF Spaces to use main.py
74
+ ```
75
+
76
+ ### Environment Detection
77
+
78
+ Both files automatically detect if running on HF Spaces:
79
+
80
+ ```python
81
+ try:
82
+ from spaces import GPU
83
+ is_hf_spaces = True
84
+ except ImportError:
85
+ is_hf_spaces = False
86
+ ```
87
+
88
+ **On HF Spaces:**
89
+ - `share=False` (HF Spaces provides its own URL)
90
+ - No warnings about share being unsupported
91
+
92
+ **Locally:**
93
+ - `share=True` (creates Gradio public link for external access)
94
+
95
+ ## Benefits
96
+
97
+ 1. βœ… **No Port Conflicts**: Only one Gradio instance launches
98
+ 2. βœ… **Clean Separation**: Interface logic (app.py) vs. Launch logic (main.py)
99
+ 3. βœ… **Flexible Testing**: Can test app.py independently
100
+ 4. βœ… **HF Spaces Compatible**: Follows HF Spaces deployment patterns
101
+ 5. βœ… **Environment Aware**: Automatically adjusts configuration based on deployment environment
102
+
103
+ ## Verification
104
+
105
+ ### Check That Only One Instance Launches
106
+
107
+ When running on HF Spaces:
108
+ ```bash
109
+ # Should see only one launch message:
110
+ "βœ… Application ready for launch"
111
+ ```
112
+
113
+ ### Check Port Binding
114
+
115
+ ```bash
116
+ # Should only see one process on port 7860
117
+ netstat -ano | findstr :7860 # Windows
118
+ lsof -i :7860 # Linux/Mac
119
+ ```
120
+
121
+ ### Check Logs
122
+
123
+ **When main.py is entry point (HF Spaces):**
124
+ ```
125
+ πŸš€ Starting AI Research Assistant MVP
126
+ Creating interface from app.py (all handlers already initialized)...
127
+ βœ“ Interface created with all API endpoints and handlers
128
+ βœ“ Detected Hugging Face Spaces - using built-in public URL
129
+ βœ… Application ready for launch
130
+ ```
131
+
132
+ **When app.py is executed directly (local):**
133
+ ```
134
+ STARTING APP (direct execution)
135
+ βœ“ Interface created
136
+ LAUNCHING GRADIO APP
137
+ Creating public Gradio share link for external access... (if not on HF Spaces)
138
+ ```
139
+
140
+ ## Troubleshooting
141
+
142
+ ### Issue: Port Still in Use
143
+
144
+ **Check:**
145
+ 1. Only one entry point is being executed
146
+ 2. No other Python processes using port 7860
147
+ 3. Previous Gradio instance was properly terminated
148
+
149
+ **Solution:**
150
+ ```bash
151
+ # Kill any existing Python processes
152
+ taskkill /IM python.exe /F # Windows
153
+ pkill -f python # Linux/Mac
154
+ ```
155
+
156
+ ### Issue: app.py Launching When Imported
157
+
158
+ **Check:** Verify `if __name__ == "__main__":` block is present and correctly indented
159
+
160
+ **Solution:** This should never happen - Python's import mechanism prevents it. If it does, check for syntax errors or circular imports.
161
+
162
+ ### Issue: API Endpoints Not Available
163
+
164
+ **Check:**
165
+ 1. `show_api=True` is set in launch configuration
166
+ 2. API endpoints are registered in app.py (before import)
167
+ 3. Both files use the same demo instance
168
+
169
+ **Solution:** The demo instance is created in app.py and used by main.py, so endpoints should be available. Verify logs show "βœ“ API endpoint registered" messages.
170
+
171
+ ## Summary
172
+
173
+ βœ… **Conflict resolved**: Single entry point architecture
174
+ βœ… **Port conflict eliminated**: Only main.py launches Gradio
175
+ βœ… **Environment aware**: Automatically detects HF Spaces vs. local
176
+ βœ… **Flexible**: Can still run app.py directly for testing
177
+ βœ… **Production ready**: Follows HF Spaces deployment best practices
178
+
GRADIO_API_CONFLICT_DIAGNOSIS.md CHANGED
@@ -213,7 +213,8 @@ demo.launch(
213
  **Common HF Spaces Issues:**
214
  - Port 7860 is required (cannot be changed on HF Spaces)
215
  - `server_name="0.0.0.0"` is correct
216
- - `share=True` creates an additional public link (HF Spaces also provides its own URL)
 
217
 
218
  ---
219
 
@@ -317,10 +318,12 @@ python verify_api_endpoint.py http://localhost:7860
317
  ### Current Launch Configuration (app.py:2109-2116)
318
 
319
  ```python
 
 
320
  demo.launch(
321
  server_name="0.0.0.0", # Accept connections from all interfaces
322
  server_port=7860, # Default Gradio port
323
- share=True, # Creates public Gradio link for external access
324
  show_api=True, # Enable API endpoints
325
  allowed_paths=[], # Security: don't serve files
326
  blocked_paths=["/tmp", "/var", "/etc", "/home"] # Block sensitive paths
 
213
  **Common HF Spaces Issues:**
214
  - Port 7860 is required (cannot be changed on HF Spaces)
215
  - `server_name="0.0.0.0"` is correct
216
+ - `share=True` is automatically disabled on HF Spaces (they provide their own public URL)
217
+ - The code automatically detects HF Spaces and disables share to prevent warnings
218
 
219
  ---
220
 
 
318
  ### Current Launch Configuration (app.py:2109-2116)
319
 
320
  ```python
321
+ # Automatically detects HF Spaces and adjusts share setting
322
+ use_share = not SPACES_GPU_AVAILABLE # False on HF Spaces, True locally
323
  demo.launch(
324
  server_name="0.0.0.0", # Accept connections from all interfaces
325
  server_port=7860, # Default Gradio port
326
+ share=use_share, # Auto: True locally, False on HF Spaces
327
  show_api=True, # Enable API endpoints
328
  allowed_paths=[], # Security: don't serve files
329
  blocked_paths=["/tmp", "/var", "/etc", "/home"] # Block sensitive paths
app.py CHANGED
@@ -2065,9 +2065,12 @@ def initialize_orchestrator():
2065
  # Try to initialize orchestrator
2066
  initialize_orchestrator()
2067
 
 
 
 
2068
  if __name__ == "__main__":
2069
  logger.info("=" * 60)
2070
- logger.info("STARTING APP")
2071
  logger.info("=" * 60)
2072
 
2073
  demo, components = create_mobile_optimized_interface()
@@ -2106,11 +2109,19 @@ if __name__ == "__main__":
2106
  logger.info("LAUNCHING GRADIO APP")
2107
  logger.info("=" * 60)
2108
  logger.info("API endpoints available at: http://<host>:7860/api/")
2109
- logger.info("Creating public Gradio share link for external access...")
 
 
 
 
 
 
 
 
2110
  demo.launch(
2111
  server_name="0.0.0.0",
2112
  server_port=7860,
2113
- share=True, # Creates public Gradio link for external access
2114
  show_api=True, # Explicitly enable API (recommended for API access)
2115
  allowed_paths=[], # Empty list = don't serve any files (prevents file URLs)
2116
  blocked_paths=["/tmp", "/var", "/etc", "/home"] # Explicitly block sensitive paths (extra security)
 
2065
  # Try to initialize orchestrator
2066
  initialize_orchestrator()
2067
 
2068
+ # Entry point - can be run directly or imported by main.py
2069
+ # When imported, only the interface creation runs (no launch)
2070
+ # When run directly, the full app launches (for local testing)
2071
  if __name__ == "__main__":
2072
  logger.info("=" * 60)
2073
+ logger.info("STARTING APP (direct execution)")
2074
  logger.info("=" * 60)
2075
 
2076
  demo, components = create_mobile_optimized_interface()
 
2109
  logger.info("LAUNCHING GRADIO APP")
2110
  logger.info("=" * 60)
2111
  logger.info("API endpoints available at: http://<host>:7860/api/")
2112
+
2113
+ # Determine if we should create a share link
2114
+ # HF Spaces provides its own public URL, so share is not needed there
2115
+ use_share = not SPACES_GPU_AVAILABLE
2116
+ if use_share:
2117
+ logger.info("Creating public Gradio share link for external access...")
2118
+ else:
2119
+ logger.info("Running on HF Spaces - using built-in public URL (share disabled)")
2120
+
2121
  demo.launch(
2122
  server_name="0.0.0.0",
2123
  server_port=7860,
2124
+ share=use_share, # Only create share link when not on HF Spaces
2125
  show_api=True, # Explicitly enable API (recommended for API access)
2126
  allowed_paths=[], # Empty list = don't serve any files (prevents file URLs)
2127
  blocked_paths=["/tmp", "/var", "/etc", "/home"] # Explicitly block sensitive paths (extra security)
main.py CHANGED
@@ -120,63 +120,48 @@ def create_event_handlers(demo, components):
120
 
121
  return get_response_handler
122
 
123
- def setup_application():
124
- """Setup and return the Gradio application"""
125
- logger.info("Starting application setup...")
126
-
127
- # Initialize components
128
- components = initialize_components()
129
-
130
- # Create the interface
131
- logger.info("Creating mobile-optimized interface...")
132
- demo = create_mobile_optimized_interface()
133
-
134
- # Setup event handlers
135
- logger.info("Setting up event handlers...")
136
-
137
- # For now, use a simple chat interface until full integration is ready
138
- try:
139
- # Get the chat function from the demo
140
- chat_interface = demo.get_blocks().children[0] # Get first component
141
-
142
- # Simple message handling for MVP
143
- def simple_chat_fn(message, history):
144
- if components.get('mock_mode'):
145
- return f"I'm running in mock mode. You said: {message}"
146
- else:
147
- return f"System is processing: {message}"
148
-
149
- # Set the chat function
150
- if hasattr(chat_interface, 'chat_fn'):
151
- chat_interface.chat_fn = simple_chat_fn
152
-
153
- except Exception as e:
154
- logger.warning(f"Could not setup advanced handlers: {e}")
155
-
156
- logger.info("Application setup completed")
157
- return demo
158
-
159
  def main():
160
  """Main entry point for HF Spaces"""
161
  logger.info("πŸš€ Starting AI Research Assistant MVP")
 
162
 
163
  # Check for HF Token
164
  hf_token = os.getenv('HF_TOKEN')
165
  if not hf_token:
166
  logger.warning("HF_TOKEN not found in environment. Some features may be limited.")
167
 
168
- # Create and launch application
169
- demo = setup_application()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
- # Launch configuration for HF Spaces
 
 
172
  launch_config = {
173
  'server_name': '0.0.0.0',
174
  'server_port': 7860,
175
- 'share': True, # Creates public Gradio link for external access
 
176
  'debug': False
177
  }
178
 
 
179
  logger.info("βœ… Application ready for launch")
 
180
  return demo.launch(**launch_config)
181
 
182
  if __name__ == "__main__":
 
120
 
121
  return get_response_handler
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  def main():
124
  """Main entry point for HF Spaces"""
125
  logger.info("πŸš€ Starting AI Research Assistant MVP")
126
+ logger.info("=" * 60)
127
 
128
  # Check for HF Token
129
  hf_token = os.getenv('HF_TOKEN')
130
  if not hf_token:
131
  logger.warning("HF_TOKEN not found in environment. Some features may be limited.")
132
 
133
+ # Import the already-configured interface from app.py
134
+ # This imports the interface without triggering app.py's launch code
135
+ # (app.py's launch only runs when app.py is executed directly, not when imported)
136
+ logger.info("Creating interface from app.py (all handlers already initialized)...")
137
+ demo, components = create_mobile_optimized_interface()
138
+
139
+ logger.info("βœ“ Interface created with all API endpoints and handlers")
140
+
141
+ # Detect if running on HF Spaces
142
+ # HF Spaces provides its own public URL, so share is not needed
143
+ try:
144
+ from spaces import GPU
145
+ is_hf_spaces = True
146
+ logger.info("βœ“ Detected Hugging Face Spaces - using built-in public URL")
147
+ except ImportError:
148
+ is_hf_spaces = False
149
+ logger.info("βœ“ Local deployment - will create Gradio share link if needed")
150
 
151
+ # Launch configuration
152
+ # Note: show_api=True is already set in app.py's interface creation,
153
+ # but we ensure it here as well for clarity
154
  launch_config = {
155
  'server_name': '0.0.0.0',
156
  'server_port': 7860,
157
+ 'share': not is_hf_spaces, # Only create share link when not on HF Spaces
158
+ 'show_api': True, # Enable API endpoints (also set in app.py, but explicit here)
159
  'debug': False
160
  }
161
 
162
+ logger.info("=" * 60)
163
  logger.info("βœ… Application ready for launch")
164
+ logger.info("=" * 60)
165
  return demo.launch(**launch_config)
166
 
167
  if __name__ == "__main__":