ZahirJS commited on
Commit
7c43635
·
verified ·
1 Parent(s): 4b7d11d

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -0
app.py ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ from graphviz import Digraph
4
+ import os
5
+ from typing import Dict, Any
6
+
7
+ def generate_concept_map(json_input: str) -> str:
8
+ """
9
+ Generates a concept map from structured JSON
10
+
11
+ Args:
12
+ json_input (str): JSON describing the concept map structure.
13
+ Required format:
14
+ {
15
+ "central_node": "Main concept",
16
+ "nodes": [
17
+ {
18
+ "id": "unique_identifier",
19
+ "label": "Node label",
20
+ "relationship": "Relationship to parent",
21
+ "subnodes": [...] # Optional
22
+ }
23
+ ]
24
+ }
25
+
26
+ Returns:
27
+ str: Image URL (compatible with Hugging Face Spaces)
28
+
29
+ Raises:
30
+ ValueError: If JSON doesn't meet required format
31
+ """
32
+ try:
33
+ # Validate input
34
+ if not json_input.strip():
35
+ return "Error: Empty input"
36
+
37
+ data = json.loads(json_input)
38
+
39
+ # Validate basic structure
40
+ if 'central_node' not in data or 'nodes' not in data:
41
+ raise ValueError("Missing required fields: central_node or nodes")
42
+
43
+ # Create graph
44
+ dot = Digraph(
45
+ name='ConceptMap',
46
+ format='png',
47
+ graph_attr={
48
+ 'rankdir': 'TB',
49
+ 'splines': 'ortho',
50
+ 'bgcolor': 'transparent'
51
+ }
52
+ )
53
+
54
+ # Central node
55
+ dot.node(
56
+ 'central',
57
+ data['central_node'],
58
+ shape='ellipse',
59
+ style='filled',
60
+ fillcolor='#2196F3',
61
+ fontcolor='white',
62
+ fontsize='14'
63
+ )
64
+
65
+ # Process nodes
66
+ for node in data['nodes']:
67
+ node_id = node.get('id')
68
+ label = node.get('label')
69
+ relationship = node.get('relationship')
70
+
71
+ # Validate node
72
+ if not all([node_id, label, relationship]):
73
+ raise ValueError(f"Invalid node: {node}")
74
+
75
+ # Create main node
76
+ dot.node(
77
+ node_id,
78
+ label,
79
+ shape='box',
80
+ style='filled',
81
+ fillcolor='#4CAF50',
82
+ fontcolor='white',
83
+ fontsize='12'
84
+ )
85
+
86
+ # Connect to central node
87
+ dot.edge(
88
+ 'central',
89
+ node_id,
90
+ label=relationship,
91
+ color='#9C27B0',
92
+ fontsize='10'
93
+ )
94
+
95
+ # Process subnodes
96
+ for subnode in node.get('subnodes', []):
97
+ sub_id = subnode.get('id')
98
+ sub_label = subnode.get('label')
99
+ sub_rel = subnode.get('relationship')
100
+
101
+ if not all([sub_id, sub_label, sub_rel]):
102
+ raise ValueError(f"Invalid subnode: {subnode}")
103
+
104
+ dot.node(
105
+ sub_id,
106
+ sub_label,
107
+ shape='diamond',
108
+ style='filled',
109
+ fillcolor='#FF5722',
110
+ fontcolor='white',
111
+ fontsize='10'
112
+ )
113
+
114
+ dot.edge(
115
+ node_id,
116
+ sub_id,
117
+ label=sub_rel,
118
+ color='#E91E63',
119
+ fontsize='8'
120
+ )
121
+
122
+ # Save image
123
+ filename = f"/tmp/concept_map_{hash(json_input)}.gv"
124
+ dot.render(filename, format='png', cleanup=True)
125
+
126
+ # Return Hugging Face compatible URL
127
+ return f"/file={filename}.png"
128
+
129
+ except json.JSONDecodeError:
130
+ return "Error: Invalid JSON"
131
+ except Exception as e:
132
+ return f"Error: {str(e)}"
133
+
134
+ if __name__ == "__main__":
135
+ demo = gr.Interface(
136
+ fn=generate_concept_map,
137
+ inputs=gr.Textbox(
138
+ placeholder="Paste structured JSON here...",
139
+ label="JSON Input",
140
+ lines=15
141
+ ),
142
+ outputs=gr.Textbox(
143
+ label="Image URL",
144
+ placeholder="Concept map URL will be generated here"
145
+ ),
146
+ title="Concept Map Generator",
147
+ description="Create concept maps from JSON (Claude compatible)"
148
+ )
149
+
150
+ # Hugging Face Spaces configuration
151
+ demo.launch(
152
+ mcp_server=True,
153
+ share=False,
154
+ server_port=int(os.getenv('PORT', 7860)),
155
+ server_name="0.0.0.0"
156
+ )