baconnier commited on
Commit
47f3b7c
·
verified ·
1 Parent(s): 2cfc841

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +130 -110
app.py CHANGED
@@ -5,6 +5,8 @@ from dotenv import load_dotenv
5
  from art_explorer import ExplorationPathGenerator
6
  from typing import Dict, Any, Optional, Union
7
  from datetime import datetime
 
 
8
 
9
  # Load environment variables
10
  load_dotenv()
@@ -19,6 +21,57 @@ except Exception as e:
19
  print(f"Error initializing ExplorationPathGenerator: {e}")
20
  raise
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  def format_output(result: Dict[str, Any]) -> str:
23
  """Format the exploration result for display with error handling"""
24
  try:
@@ -31,13 +84,7 @@ def format_output(result: Dict[str, Any]) -> str:
31
  }, indent=2)
32
 
33
  def parse_json_input(json_str: str, default_value: Any) -> Any:
34
- """
35
- Safely parse JSON input with detailed error handling
36
-
37
- Args:
38
- json_str: JSON string to parse
39
- default_value: Fallback value if parsing fails
40
- """
41
  if not json_str or json_str.strip() in ('', '{}', '[]'):
42
  return default_value
43
  try:
@@ -53,7 +100,7 @@ def validate_parameters(
53
  ) -> Dict[str, Any]:
54
  """Validate and merge exploration parameters"""
55
  validated_params = {
56
- "depth": max(1, min(10, depth)), # Clamp depth between 1-10
57
  "domain": domain if domain.strip() else None,
58
  "previous_explorations": []
59
  }
@@ -67,48 +114,34 @@ def explore(
67
  parameters: str = "{}",
68
  depth: int = 5,
69
  domain: str = ""
70
- ) -> str:
71
- """
72
- Generate exploration path based on user input with comprehensive error handling
73
-
74
- Args:
75
- query (str): User's exploration query
76
- path_history (str): JSON string of previous exploration path
77
- parameters (str): JSON string of exploration parameters
78
- depth (int): Exploration depth parameter (1-10)
79
- domain (str): Specific domain context
80
-
81
- Returns:
82
- str: Formatted JSON string of exploration results or error message
83
- """
84
  try:
85
- # Input validation
86
  if not query.strip():
87
  raise ValueError("Query cannot be empty")
88
 
89
- # Parse and validate inputs
90
  selected_path = parse_json_input(path_history, [])
91
  custom_parameters = parse_json_input(parameters, {})
92
-
93
- # Validate and merge parameters
94
  exploration_parameters = validate_parameters(depth, domain, custom_parameters)
95
 
96
- # Debug logging
97
  print(f"Processing query: {query}")
98
  print(f"Parameters: {json.dumps(exploration_parameters, indent=2)}")
99
 
100
- # Generate exploration path - FIXED HERE: changed user_query to query
101
  result = generator.generate_exploration_path(
102
- query=query, # Changed from user_query to query
103
  selected_path=selected_path,
104
  exploration_parameters=exploration_parameters
105
  )
106
 
107
- # Validate result
108
  if not isinstance(result, dict):
109
  raise ValueError("Invalid response format from generator")
110
 
111
- return format_output(result)
 
 
 
 
 
112
 
113
  except Exception as e:
114
  error_response = {
@@ -122,101 +155,88 @@ def explore(
122
  }
123
  }
124
  print(f"Error in explore function: {e}")
125
- return format_output(error_response)
126
 
127
- def create_interface() -> gr.Interface:
128
- """Create and configure the Gradio interface with enhanced examples and documentation"""
129
 
130
- inputs = [
131
- gr.Textbox(
132
- label="Exploration Query",
133
- placeholder="Enter your art history exploration query...",
134
- lines=2
135
- ),
136
- gr.Textbox(
137
- label="Path History (JSON)",
138
- placeholder="[]",
139
- lines=3,
140
- value="[]"
141
- ),
142
- gr.Textbox(
143
- label="Additional Parameters (JSON)",
144
- placeholder="{}",
145
- lines=3,
146
- value="{}"
147
- ),
148
- gr.Slider(
149
- label="Exploration Depth",
150
- minimum=1,
151
- maximum=10,
152
- value=5,
153
- step=1
154
- ),
155
- gr.Textbox(
156
- label="Domain Context",
157
- placeholder="Optional: Specify art history period or movement",
158
- lines=1
159
- )
160
- ]
161
-
162
- output = gr.Textbox(
163
- label="Exploration Result",
164
- lines=20
165
- )
166
-
167
- examples = [
168
- [
169
- "Explore the evolution of Renaissance painting techniques",
170
- "[]",
171
- "{}",
172
- 5,
173
- "Renaissance"
174
- ],
175
- [
176
- "Investigate the influence of Japanese art on Impressionism",
177
- "[]",
178
- "{}",
179
- 7,
180
- "Impressionism"
181
- ],
182
- [
183
- "Analyze the development of Cubism through Picasso's work",
184
- "[]",
185
- "{}",
186
- 6,
187
- "Cubism"
188
- ]
189
- ]
190
-
191
- return gr.Interface(
192
- fn=explore,
193
- inputs=inputs,
194
- outputs=output,
195
- title="Art History Exploration Path Generator",
196
- description="""Generate structured exploration paths for art history queries.
197
 
198
  ## Features:
199
  - Dynamic exploration path generation
200
  - Contextual understanding of art history
201
  - Multi-dimensional analysis
202
  - Customizable exploration depth
 
203
 
204
  ## Usage:
205
  1. Enter your art history query
206
  2. Adjust exploration depth (1-10)
207
  3. Optionally specify domain context
208
- 4. View generated exploration path""",
209
- examples=examples,
210
- theme="default",
211
- analytics_enabled=False
212
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
  if __name__ == "__main__":
215
  try:
216
  print(f"===== Application Startup at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} =====")
217
- # Create interface
218
- iface = create_interface()
219
- # Launch with custom configurations
220
- iface.launch()
221
  except Exception as e:
222
  print(f"Failed to launch interface: {e}")
 
5
  from art_explorer import ExplorationPathGenerator
6
  from typing import Dict, Any, Optional, Union
7
  from datetime import datetime
8
+ import networkx as nx
9
+ import matplotlib.pyplot as plt
10
 
11
  # Load environment variables
12
  load_dotenv()
 
21
  print(f"Error initializing ExplorationPathGenerator: {e}")
22
  raise
23
 
24
+ def create_graph_visualization(nodes):
25
+ """Create a graph visualization from exploration nodes"""
26
+ try:
27
+ # Create a new directed graph
28
+ G = nx.DiGraph()
29
+
30
+ # Add nodes to the graph
31
+ for node in nodes:
32
+ G.add_node(node['id'],
33
+ title=node['title'],
34
+ description=node['description'],
35
+ depth=node['depth'])
36
+
37
+ # Add edges based on connections
38
+ for node in nodes:
39
+ for conn in node['connections']:
40
+ G.add_edge(node['id'],
41
+ conn['target_id'],
42
+ weight=conn.get('relevance_score', 0))
43
+
44
+ # Create the plot
45
+ plt.figure(figsize=(12, 8))
46
+
47
+ # Use different colors for different depths
48
+ colors = ['#FF9999', '#99FF99', '#9999FF', '#FFFF99']
49
+ node_colors = [colors[G.nodes[node]['depth'] % len(colors)] for node in G.nodes()]
50
+
51
+ # Create layout
52
+ pos = nx.spring_layout(G, k=1, iterations=50)
53
+
54
+ # Draw the graph
55
+ nx.draw(G, pos,
56
+ node_color=node_colors,
57
+ with_labels=True,
58
+ labels={node: G.nodes[node]['title'] for node in G.nodes()},
59
+ node_size=2000,
60
+ font_size=8,
61
+ font_weight='bold',
62
+ arrows=True,
63
+ edge_color='gray',
64
+ width=1)
65
+
66
+ # Save to a temporary file
67
+ plt.savefig('temp_graph.png', format='png', dpi=300, bbox_inches='tight')
68
+ plt.close()
69
+
70
+ return 'temp_graph.png'
71
+ except Exception as e:
72
+ print(f"Error creating graph visualization: {e}")
73
+ return None
74
+
75
  def format_output(result: Dict[str, Any]) -> str:
76
  """Format the exploration result for display with error handling"""
77
  try:
 
84
  }, indent=2)
85
 
86
  def parse_json_input(json_str: str, default_value: Any) -> Any:
87
+ """Safely parse JSON input with detailed error handling"""
 
 
 
 
 
 
88
  if not json_str or json_str.strip() in ('', '{}', '[]'):
89
  return default_value
90
  try:
 
100
  ) -> Dict[str, Any]:
101
  """Validate and merge exploration parameters"""
102
  validated_params = {
103
+ "depth": max(1, min(10, depth)),
104
  "domain": domain if domain.strip() else None,
105
  "previous_explorations": []
106
  }
 
114
  parameters: str = "{}",
115
  depth: int = 5,
116
  domain: str = ""
117
+ ) -> tuple[str, Optional[str]]:
118
+ """Generate exploration path and visualization"""
 
 
 
 
 
 
 
 
 
 
 
 
119
  try:
 
120
  if not query.strip():
121
  raise ValueError("Query cannot be empty")
122
 
 
123
  selected_path = parse_json_input(path_history, [])
124
  custom_parameters = parse_json_input(parameters, {})
 
 
125
  exploration_parameters = validate_parameters(depth, domain, custom_parameters)
126
 
 
127
  print(f"Processing query: {query}")
128
  print(f"Parameters: {json.dumps(exploration_parameters, indent=2)}")
129
 
 
130
  result = generator.generate_exploration_path(
131
+ query=query,
132
  selected_path=selected_path,
133
  exploration_parameters=exploration_parameters
134
  )
135
 
 
136
  if not isinstance(result, dict):
137
  raise ValueError("Invalid response format from generator")
138
 
139
+ # Create graph visualization if we have nodes
140
+ graph_path = None
141
+ if result.get("nodes"):
142
+ graph_path = create_graph_visualization(result["nodes"])
143
+
144
+ return format_output(result), graph_path
145
 
146
  except Exception as e:
147
  error_response = {
 
155
  }
156
  }
157
  print(f"Error in explore function: {e}")
158
+ return format_output(error_response), None
159
 
160
+ def create_interface() -> gr.Blocks:
161
+ """Create and configure the Gradio interface"""
162
 
163
+ with gr.Blocks(title="Art History Exploration Path Generator") as interface:
164
+ gr.Markdown("""# Art History Exploration Path Generator
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
  ## Features:
167
  - Dynamic exploration path generation
168
  - Contextual understanding of art history
169
  - Multi-dimensional analysis
170
  - Customizable exploration depth
171
+ - Interactive visualization
172
 
173
  ## Usage:
174
  1. Enter your art history query
175
  2. Adjust exploration depth (1-10)
176
  3. Optionally specify domain context
177
+ 4. View generated exploration path and visualization""")
178
+
179
+ with gr.Row():
180
+ with gr.Column():
181
+ query_input = gr.Textbox(
182
+ label="Exploration Query",
183
+ placeholder="Enter your art history exploration query...",
184
+ lines=2
185
+ )
186
+ path_history = gr.Textbox(
187
+ label="Path History (JSON)",
188
+ placeholder="[]",
189
+ lines=3,
190
+ value="[]"
191
+ )
192
+ parameters = gr.Textbox(
193
+ label="Additional Parameters (JSON)",
194
+ placeholder="{}",
195
+ lines=3,
196
+ value="{}"
197
+ )
198
+ depth = gr.Slider(
199
+ label="Exploration Depth",
200
+ minimum=1,
201
+ maximum=10,
202
+ value=5,
203
+ step=1
204
+ )
205
+ domain = gr.Textbox(
206
+ label="Domain Context",
207
+ placeholder="Optional: Specify art history period or movement",
208
+ lines=1
209
+ )
210
+ generate_btn = gr.Button("Generate Exploration Path")
211
+
212
+ with gr.Column():
213
+ text_output = gr.JSON(label="Exploration Result")
214
+ graph_output = gr.Image(label="Exploration Graph")
215
+
216
+ examples = [
217
+ ["Explore the evolution of Renaissance painting techniques", "[]", "{}", 5, "Renaissance"],
218
+ ["Investigate the influence of Japanese art on Impressionism", "[]", "{}", 7, "Impressionism"],
219
+ ["Analyze the development of Cubism through Picasso's work", "[]", "{}", 6, "Cubism"]
220
+ ]
221
+
222
+ gr.Examples(
223
+ examples=examples,
224
+ inputs=[query_input, path_history, parameters, depth, domain]
225
+ )
226
+
227
+ generate_btn.click(
228
+ fn=explore,
229
+ inputs=[query_input, path_history, parameters, depth, domain],
230
+ outputs=[text_output, graph_output]
231
+ )
232
+
233
+ return interface
234
 
235
  if __name__ == "__main__":
236
  try:
237
  print(f"===== Application Startup at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} =====")
238
+ # Create and launch interface
239
+ demo = create_interface()
240
+ demo.launch()
 
241
  except Exception as e:
242
  print(f"Failed to launch interface: {e}")