mgbam commited on
Commit
2bd0651
·
verified ·
1 Parent(s): 9ce91b0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +160 -172
app.py CHANGED
@@ -1,186 +1,174 @@
1
  # app.py
 
 
2
  import sys
3
  import os
4
- import importlib.util # Import the utility
5
- import traceback # Import traceback for detailed error printing
6
-
7
- print("--- DETAILED DEBUG INFO ---")
8
- print(f"Python Version: {sys.version}")
9
- print(f"Current Working Directory: {os.getcwd()}")
10
- print("sys.path:")
11
- for p in sys.path:
12
- print(f" - {p}")
13
-
14
- print("\n--- Checking Directory Structure ---")
15
- root_contents = []
16
- try:
17
- root_contents = os.listdir('.')
18
- except Exception as e:
19
- print(f"[ERROR] Could not list root directory contents: {e}")
20
- print(f"Root Directory Contents: {root_contents}")
21
-
22
- src_path = os.path.join(os.getcwd(), 'src')
23
- if os.path.exists(src_path) and os.path.isdir(src_path):
24
- print(f"\n[OK] src Directory ('{src_path}') Exists.")
25
- try:
26
- src_contents = os.listdir(src_path)
27
- print(f" src Contents: {src_contents}")
28
-
29
- chimera_path = os.path.join(src_path, 'chimera')
30
- if os.path.exists(chimera_path) and os.path.isdir(chimera_path):
31
- print(f" [OK] chimera Directory ('{chimera_path}') Exists.")
32
- try:
33
- chimera_contents = os.listdir(chimera_path)
34
- print(f" chimera Contents: {chimera_contents}")
35
-
36
- # Explicitly check for __init__.py in chimera
37
- chimera_init_path = os.path.join(chimera_path, '__init__.py')
38
- if os.path.exists(chimera_init_path):
39
- print(" [OK] src/chimera/__init__.py Exists.")
40
- else:
41
- print(" [ERROR] src/chimera/__init__.py MISSING!")
42
-
43
- core_path = os.path.join(chimera_path, 'core')
44
- if os.path.exists(core_path) and os.path.isdir(core_path):
45
- print(f" [OK] core Directory ('{core_path}') Exists.")
46
- try:
47
- core_contents = os.listdir(core_path)
48
- print(f" core Contents: {core_contents}")
49
-
50
- # Explicitly check for __init__.py in core
51
- core_init_path = os.path.join(core_path, '__init__.py')
52
- if os.path.exists(core_init_path):
53
- print(" [OK] src/chimera/core/__init__.py Exists.")
54
- else:
55
- print(" [ERROR] src/chimera/core/__init__.py MISSING!")
56
-
57
- orchestrator_path = os.path.join(core_path, 'orchestrator.py')
58
- if os.path.exists(orchestrator_path):
59
- print(f" [OK] orchestrator.py ('{orchestrator_path}') Exists.")
60
- else:
61
- print(f" [ERROR] orchestrator.py ('{orchestrator_path}') MISSING!")
62
- except Exception as e:
63
- print(f" [ERROR] Could not list core directory contents: {e}")
64
- else:
65
- print(f" [ERROR] core Directory ('{core_path}') MISSING or is not a directory.")
66
- except Exception as e:
67
- print(f" [ERROR] Could not list chimera directory contents: {e}")
68
- else:
69
- print(f" [ERROR] chimera Directory ('{chimera_path}') MISSING or is not a directory.")
70
- except Exception as e:
71
- print(f"\n[ERROR] Could not list src directory contents: {e}")
72
- else:
73
- print(f"\n[ERROR] src Directory ('{src_path}') MISSING or is not a directory.")
74
-
75
 
76
- # --- Test importability using importlib ---
77
- module_name_to_test = "src.chimera.core.orchestrator"
78
- print(f"\n--- Testing importability of '{module_name_to_test}' using importlib ---")
79
- spec = None
80
  try:
81
- # Clear any previous import attempts from sys.modules that might interfere
82
- if module_name_to_test in sys.modules:
83
- del sys.modules[module_name_to_test]
84
- # Also potentially clear parent modules if issues persist
85
- # if "src.chimera.core" in sys.modules: del sys.modules["src.chimera.core"]
86
- # if "src.chimera" in sys.modules: del sys.modules["src.chimera"]
87
- # if "src" in sys.modules: del sys.modules["src"]
88
-
89
- spec = importlib.util.find_spec(module_name_to_test)
90
- except Exception as e:
91
- print(f"[ERROR] Exception during importlib.util.find_spec: {type(e).__name__}: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  traceback.print_exc()
93
-
94
- if spec is None:
95
- print(f"[FAIL] importlib.util.find_spec could NOT find module '{module_name_to_test}'.")
96
- print(" This means Python's import machinery cannot locate this module.")
97
- print(" Double-check directory names, __init__.py files, and potential typos.")
98
- else:
99
- print(f"[OK] importlib.util.find_spec found module '{module_name_to_test}'.")
100
- print(f" Module Location Hint: {spec.origin}")
101
- # If found, try to actually import it to see if loading fails
102
- print(f"\n--- Attempting direct import of '{module_name_to_test}' using importlib.import_module ---")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  try:
104
- imported_module = importlib.import_module(module_name_to_test)
105
- print(f"[OK] Successfully imported '{module_name_to_test}'. Module type: {type(imported_module)}")
106
- # Try accessing the function
107
- if hasattr(imported_module, 'run_analysis'):
108
- print("[OK] Function 'run_analysis' found in the imported module.")
109
- else:
110
- print("[ERROR] Function 'run_analysis' NOT FOUND in the imported module!")
111
  except Exception as e:
112
- print(f"[FAIL] Error occurred DURING import of '{module_name_to_test}':")
113
- traceback.print_exc() # Print the full traceback for the import error
 
 
 
114
 
115
- print("\n--- Attempting original failing import ---")
 
 
 
116
  try:
117
- # Ensure sys.modules cache is clean before this attempt too
118
- if module_name_to_test in sys.modules: del sys.modules[module_name_to_test]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
- from src.chimera.core.orchestrator import run_analysis
121
- print("[OK] Original 'from ... import ...' statement SUCCEEDED.")
122
- # If this succeeds now, the issue might have been temporary or fixed by restart
123
- except ModuleNotFoundError:
124
- print("[FAIL] Original 'from ... import ...' statement FAILED with ModuleNotFoundError.")
125
- print(" Refer to the importlib test above for clues.")
126
- traceback.print_exc() # Also print traceback for ModuleNotFoundError
127
  except Exception as e:
128
- print(f"[FAIL] Original 'from ... import ...' statement FAILED with a different error:")
 
 
129
  traceback.print_exc()
130
 
131
- print("\n--- End of Debug Script ---")
132
-
133
- # Prevent Gradio from starting since imports might have failed
134
- # ===============================================================
135
- # == COMMENT OUT OR REMOVE GRADIO CODE BELOW FOR THIS TEST RUN ==
136
- # ===============================================================
137
- # import gradio as gr
138
- # from src.chimera.utils.logging_config import setup_logging, logger # This import would also fail if orchestrator fails
139
- # from src.chimera.config import GEMINI_API_KEY
140
-
141
- # # Setup logging as soon as the app starts
142
- # # setup_logging() # Comment out if logging_config import fails
143
-
144
- # # Check essential configurations on startup
145
- # # if not GEMINI_API_KEY:
146
- # # # logger.error("CRITICAL: GEMINI_API_KEY is not set. The application might not function correctly.")
147
- # # print("CRITICAL: GEMINI_API_KEY is not set.") # Use print during early debug
148
-
149
- # async def chimera_interface(query: str):
150
- # # Placeholder implementation for debugging
151
- # print(f"Gradio interface received query (debug): {query}")
152
- # if not query:
153
- # return "Please enter a query."
154
- # # logger.info(f"Gradio interface received query: {query}")
155
- # try:
156
- # # Need to import run_analysis successfully first
157
- # from src.chimera.core.orchestrator import run_analysis
158
- # result = await run_analysis(query)
159
- # # logger.info("Gradio interface processing complete.")
160
- # print("Gradio interface processing complete (debug).")
161
- # return result
162
- # except NameError:
163
- # print("Error: run_analysis could not be imported for Gradio.")
164
- # return "Error: Backend function 'run_analysis' is not available due to import issues."
165
- # except Exception as e:
166
- # # logger.exception("Error in Gradio interface call to run_analysis.")
167
- # print(f"Error in Gradio interface call (debug): {e}")
168
- # traceback.print_exc()
169
- # return f"An unexpected error occurred in the backend: {e}"
170
-
171
- # # --- Gradio UI Definition ---
172
- # with gr.Blocks(theme=gr.themes.Soft(), title="Project Chimera (Debug Mode)") as demo:
173
- # gr.Markdown(
174
- # """
175
- # # Project Chimera : Real-Time Global Analysis Engine (DEBUG MODE)
176
- # Enter your query to analyze real-time data from SERP and other sources using Gemini.
177
- # (Example: "Analyze recent news about renewable energy investments in the US")
178
- # """
179
- # )
180
- # # ... rest of your Gradio UI definition ...
181
-
182
- # # --- Launching the App ---
183
- # if __name__ == "__main__":
184
- # # logger.info("Starting Gradio application...")
185
- # print("Starting Gradio application (debug)...")
186
- # # demo.launch() # Don't launch Gradio if imports fail
 
1
  # app.py
2
+ import gradio as gr
3
+ import asyncio
4
  import sys
5
  import os
6
+ import traceback # Import traceback for detailed error logging if needed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
+ # --- Attempt to import necessary components for the actual app ---
 
 
 
9
  try:
10
+ from src.chimera.core.orchestrator import run_analysis
11
+ from src.chimera.utils.logging_config import setup_logging, logger
12
+ from src.chimera.config import GEMINI_API_KEY, SERPAPI_API_KEY # Import API keys to check configuration
13
+
14
+ # --- Perform initial setup ---
15
+ setup_logging() # Initialize logging system
16
+ logger.info("Logging initialized.")
17
+
18
+ # --- Configuration Checks ---
19
+ CONFIG_ERRORS = []
20
+ if not GEMINI_API_KEY:
21
+ CONFIG_ERRORS.append("GEMINI_API_KEY is not set.")
22
+ logger.error("CRITICAL CONFIG ERROR: GEMINI_API_KEY is not set.")
23
+ if not SERPAPI_API_KEY:
24
+ # Assuming SERP is essential, make it critical too
25
+ CONFIG_ERRORS.append("SERPAPI_API_KEY is not set.")
26
+ logger.error("CRITICAL CONFIG ERROR: SERPAPI_API_KEY is not set.")
27
+ # Add checks for other essential API keys here
28
+
29
+ # --- Set flag based on configuration status ---
30
+ IS_CONFIGURED_PROPERLY = not CONFIG_ERRORS
31
+
32
+ except ImportError as e:
33
+ # Handle case where core modules cannot be imported - app cannot function
34
+ print(f"FATAL IMPORT ERROR: {e}")
35
+ print("Could not import necessary Chimera components. Ensure structure is correct and __init__.py files exist.")
36
  traceback.print_exc()
37
+ # Define dummy elements to allow the script to potentially reach the end
38
+ # but indicate a non-functional state
39
+ run_analysis = None
40
+ setup_logging = lambda: print("!!! Logging setup skipped due to import error !!!")
41
+ logger = type('DummyLogger', (object,), {'info': print, 'warning': print, 'error': print, 'exception': print})()
42
+ logger.error("!!! Logging is not properly configured due to import errors !!!")
43
+ IS_CONFIGURED_PROPERLY = False
44
+ CONFIG_ERRORS = ["Core application modules failed to import."]
45
+ print("!!! Application will not function correctly due to import errors !!!")
46
+
47
+
48
+ # --- Define the core Gradio interface function ---
49
+ async def chimera_interface(query: str):
50
+ """
51
+ Wrapper function for Gradio to call the async orchestrator.
52
+ Handles input validation, configuration checks, and calls the backend.
53
+ """
54
+ # 1. Check if the application backend is fundamentally broken (import errors)
55
+ if run_analysis is None:
56
+ logger.error("Attempted analysis but run_analysis function failed to import during startup.")
57
+ # Provide a clear error message in the UI
58
+ return "## Error: Application Backend Failed\n\nThe core analysis function could not be loaded. Please check the application logs."
59
+
60
+ # 2. Check if essential configuration (API Keys) is missing
61
+ if not IS_CONFIGURED_PROPERLY:
62
+ logger.error(f"Attempted analysis with missing configuration: {', '.join(CONFIG_ERRORS)}")
63
+ error_list = "\n".join([f"- {err}" for err in CONFIG_ERRORS])
64
+ # Provide a clear error message in the UI
65
+ return f"## Error: Application Not Configured\n\nThe following essential configurations are missing:\n{error_list}\nPlease check the application secrets/environment variables."
66
+
67
+ # 3. Check for empty user input
68
+ if not query or not query.strip():
69
+ logger.warning("Received empty query.")
70
+ # Provide guidance in the UI
71
+ return "Please enter a query in the text box above."
72
+
73
+ # 4. If all checks pass, proceed with the analysis
74
+ logger.info(f"Gradio interface received query: '{query[:100]}...'") # Log snippet
75
  try:
76
+ # Gradio handles running the async function correctly
77
+ result = await run_analysis(query)
78
+ logger.info("Gradio interface processing complete.")
79
+ # Return the result (expecting markdown formatted string from backend)
80
+ return result
 
 
81
  except Exception as e:
82
+ # Log the full error details for debugging
83
+ logger.exception(f"Unexpected error during run_analysis for query: '{query[:100]}...'")
84
+ # Provide a user-friendly error message in the UI
85
+ # Avoid exposing raw exception details directly unless intended for debugging UI
86
+ return f"## Error: Analysis Failed\n\nAn unexpected error occurred while processing your request.\nDetails have been logged by the application administrator.\n\n*(Error type: {type(e).__name__})*"
87
 
88
+
89
+ # --- Gradio UI Definition ---
90
+ # Use a try-except block to catch errors during UI construction
91
+ demo = None # Initialize demo to None
92
  try:
93
+ with gr.Blocks(theme=gr.themes.Soft(), title="Project Chimera") as demo:
94
+ # Display configuration errors prominently if they exist
95
+ if not IS_CONFIGURED_PROPERLY:
96
+ config_error_msg = "\n".join([f"- {err}" for err in CONFIG_ERRORS])
97
+ gr.Markdown(
98
+ f"""
99
+ ## ⚠️ Application Configuration Error
100
+ The application cannot function correctly because the following configurations are missing:
101
+ {config_error_msg}
102
+ Please contact the administrator or check the environment secrets.
103
+ """,
104
+ elem_id="config_error_banner"
105
+ )
106
+
107
+ # Main UI components
108
+ gr.Markdown(
109
+ """
110
+ # Project Chimera : Real-Time Global Analysis Engine
111
+ Enter your query to analyze real-time data from SERP and other sources using Gemini.
112
+ *(Example: "Analyze recent news about renewable energy investments in the US")*
113
+ """
114
+ )
115
+ with gr.Row():
116
+ query_input = gr.Textbox(
117
+ label="Your Query:",
118
+ placeholder="Type your complex question or analysis request here...",
119
+ lines=3,
120
+ elem_id="query_input_box"
121
+ )
122
+ submit_button = gr.Button("Analyze", variant="primary", elem_id="submit_button")
123
+ with gr.Row():
124
+ # Using Markdown for output allows richer formatting (like headers from error messages)
125
+ output_display = gr.Markdown(label="Chimera Analysis:", elem_id="output_display_markdown")
126
+
127
+ # Link the button click to the interface function
128
+ submit_button.click(
129
+ fn=chimera_interface,
130
+ inputs=[query_input],
131
+ outputs=[output_display],
132
+ # Add API name for potential tracking/analytics if needed by Gradio
133
+ # api_name="chimera_analysis"
134
+ )
135
+
136
+ # Example usage display
137
+ gr.Examples(
138
+ examples=[
139
+ "Search recent news about AI impact on healthcare.",
140
+ "What are the latest developments in fusion energy according to recent searches?",
141
+ "Summarize the latest discussion around supply chain disruptions.",
142
+ "What are recent news headlines mentioning 'geopolitical tensions'?"
143
+ ],
144
+ inputs=[query_input],
145
+ outputs=[output_display],
146
+ fn=chimera_interface, # Make examples clickable
147
+ cache_examples=False, # Avoid caching as results depend on real-time data
148
+ elem_id="examples_section"
149
+ )
150
 
 
 
 
 
 
 
 
151
  except Exception as e:
152
+ logger.exception("FATAL: Failed to build Gradio interface.")
153
+ # demo remains None if gr.Blocks fails
154
+ print(f"Error creating Gradio Blocks: {e}")
155
  traceback.print_exc()
156
 
157
+
158
+ # --- Launching the App ---
159
+ if __name__ == "__main__":
160
+ if demo and IS_CONFIGURED_PROPERLY and run_analysis is not None:
161
+ # Only launch if Gradio Blocks were created AND config is okay AND core function loaded
162
+ logger.info("Starting Gradio application...")
163
+ # Standard launch for Hugging Face Spaces
164
+ # queue() can be added for better handling of concurrent users if needed: demo.queue().launch()
165
+ demo.launch()
166
+ elif not demo:
167
+ logger.error("Gradio application blocks failed to initialize. Cannot launch.")
168
+ print("Application launch aborted due to UI build errors.")
169
+ else:
170
+ # Handles cases where config failed or run_analysis didn't import
171
+ logger.error("Application launch aborted due to configuration errors or failed imports.")
172
+ print("Application launch aborted. Please check configuration and import logs.")
173
+ # Keep the container running but without the app interface (or exit)
174
+ # Depending on HF Spaces behavior, it might restart or just show logs