mgokg commited on
Commit
07492c4
·
verified ·
1 Parent(s): ad2c811

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +187 -70
app.py CHANGED
@@ -1,87 +1,204 @@
1
- import base64
2
  import gradio as gr
3
  import os
4
  import json
5
- from google import genai
6
- from google.genai import types
7
- from gradio_client import Client
 
 
8
 
9
-
10
- def clean_json_string(json_str):
11
- """
12
- Removes any comments or prefixes before the actual JSON content.
13
- """
14
- # Find the first occurrence of '{'
15
- json_start = json_str.find('{')
16
- if json_start == -1:
17
- # If no '{' is found, try with '[' for arrays
18
- json_start = json_str.find('[')
19
- if json_start == -1:
20
- return json_str # Return original if no JSON markers found
21
 
22
- # Extract everything from the first JSON marker
23
- cleaned_str = json_str[json_start:]
24
- return cleaned_str
25
- # Verify it's valid JSON
26
- try:
27
- json.loads(cleaned_str)
28
- return cleaned_str
29
- except json.JSONDecodeError:
30
- return json_str # Return original if cleaning results in invalid JSON
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
- def generate(input_text):
 
 
 
 
 
 
 
33
  try:
34
- client = genai.Client(
35
- api_key=os.environ.get("GEMINI_API_KEY"),
36
- )
37
  except Exception as e:
38
- return f"Error initializing client: {e}. Make sure GEMINI_API_KEY is set."
39
 
40
- model = "gemini-flash-latest"
41
- contents = [
42
- types.Content(
43
- role="user",
44
- parts=[
45
- types.Part.from_text(text=f"{input_text}"),
46
- ],
47
- ),
48
- ]
49
- tools = [
50
- types.Tool(google_search=types.GoogleSearch()),
51
- ]
52
- generate_content_config = types.GenerateContentConfig(
53
- temperature=0.4,
54
- thinking_config = types.ThinkingConfig(
55
- thinking_budget=0,
56
- ),
57
- tools=tools,
58
- response_mime_type="text/plain",
59
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
 
62
- response_text = ""
 
63
  try:
64
- for chunk in client.models.generate_content_stream(
65
- model=model,
66
- contents=contents,
67
- config=generate_content_config,
68
- ):
69
- response_text += chunk.text
70
  except Exception as e:
71
- return f"Error during generation: {e}"
72
- data = response_text
73
- #data = clean_json_string(response_text)
74
- data = data[:-1]
75
- return response_text, ""
76
-
77
 
78
- if __name__ == '__main__':
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  with gr.Blocks() as demo:
81
- title=gr.Markdown("# Gemini 2.0 Flash + Websearch")
 
 
 
 
 
 
 
 
 
82
  output_textbox = gr.Markdown()
83
- input_textbox = gr.Textbox(lines=3, label="", placeholder="Enter message here...")
84
- submit_button = gr.Button("send")
85
- submit_button.click(fn=generate,inputs=input_textbox,outputs=[output_textbox, input_textbox])
86
- demo.launch(show_error=True)
87
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import os
3
  import json
4
+ import asyncio
5
+ from typing import Optional
6
+ from mcp import ClientSession, StdioServerParameters
7
+ from mcp.client.stdio import stdio_client
8
+ import httpx
9
 
10
+ class MCPTrainClient:
11
+ """MCP Client für Zugverbindungsabfragen"""
 
 
 
 
 
 
 
 
 
 
12
 
13
+ def __init__(self, server_url: str):
14
+ self.server_url = server_url
15
+ self.session: Optional[ClientSession] = None
16
+ self.tools = []
17
+
18
+ async def connect(self):
19
+ """Stelle Verbindung zum MCP-Server her"""
20
+ try:
21
+ # Für Streamable HTTP Transport verwenden wir httpx
22
+ # Die Session wird über die MCP-URL initialisiert
23
+ self.session = ClientSession()
24
+
25
+ # Tools vom Server abrufen
26
+ await self.list_tools()
27
+ return True
28
+ except Exception as e:
29
+ print(f"Verbindungsfehler: {e}")
30
+ return False
31
+
32
+ async def list_tools(self):
33
+ """Rufe verfügbare Tools vom MCP-Server ab"""
34
+ try:
35
+ if self.session:
36
+ response = await self.session.list_tools()
37
+ self.tools = response.tools
38
+ print(f"Verfügbare Tools: {[tool.name for tool in self.tools]}")
39
+ except Exception as e:
40
+ print(f"Fehler beim Abrufen der Tools: {e}")
41
+
42
+ async def call_tool(self, tool_name: str, arguments: dict):
43
+ """Rufe ein spezifisches Tool auf dem MCP-Server auf"""
44
+ try:
45
+ if not self.session:
46
+ await self.connect()
47
+
48
+ result = await self.session.call_tool(tool_name, arguments)
49
+ return result
50
+ except Exception as e:
51
+ print(f"Fehler beim Tool-Aufruf: {e}")
52
+ return None
53
+
54
+ async def search_connections(self, origin: str, destination: str):
55
+ """Suche Zugverbindungen über den MCP-Server"""
56
+ try:
57
+ # Verwende das db_timetable_api_ui_wrapper Tool
58
+ result = await self.call_tool(
59
+ "db_timetable_api_ui_wrapper",
60
+ {
61
+ "origin": origin,
62
+ "destination": destination
63
+ }
64
+ )
65
+
66
+ if result and hasattr(result, 'content'):
67
+ return self._parse_result(result.content)
68
+ return None
69
+ except Exception as e:
70
+ print(f"Fehler bei der Verbindungssuche: {e}")
71
+ return None
72
+
73
+ def _parse_result(self, content):
74
+ """Parse die Antwort vom MCP-Server"""
75
+ try:
76
+ if isinstance(content, list) and len(content) > 0:
77
+ # Extrahiere den Text aus der Antwort
78
+ if hasattr(content[0], 'text'):
79
+ return content[0].text
80
+ elif isinstance(content[0], dict) and 'text' in content[0]:
81
+ return content[0]['text']
82
+ return str(content)
83
+ except Exception as e:
84
+ print(f"Fehler beim Parsen: {e}")
85
+ return None
86
+
87
 
88
+ # Globaler MCP-Client
89
+ mcp_client = None
90
+ MCP_SERVER_URL = "https://mgokg-db-timetable-api.hf.space/gradio_api/mcp/"
91
+
92
+
93
+ async def initialize_mcp_client():
94
+ """Initialisiere den MCP-Client"""
95
+ global mcp_client
96
  try:
97
+ mcp_client = MCPTrainClient(MCP_SERVER_URL)
98
+ await mcp_client.connect()
99
+ return "MCP-Client erfolgreich initialisiert"
100
  except Exception as e:
101
+ return f"Fehler bei der Initialisierung: {e}"
102
 
103
+
104
+ async def search_train_connections_async(user_input: str):
105
+ """Asynchrone Funktion zur Suche von Zugverbindungen"""
106
+ global mcp_client
107
+
108
+ # Initialisiere Client falls noch nicht geschehen
109
+ if mcp_client is None:
110
+ await initialize_mcp_client()
111
+
112
+ try:
113
+ # Extrahiere Start und Ziel aus der Benutzereingabe
114
+ # Einfache Parsing-Logik (kann erweitert werden)
115
+ parts = user_input.lower().replace("von", "").replace("nach", "").strip().split()
116
+
117
+ if len(parts) < 2:
118
+ return "Bitte geben Sie Start- und Zielort an (z.B. 'Frankfurt nach Berlin')"
119
+
120
+ # Versuche, Start und Ziel zu identifizieren
121
+ if "nach" in user_input.lower():
122
+ split_parts = user_input.lower().split("nach")
123
+ origin = split_parts[0].replace("von", "").strip()
124
+ destination = split_parts[1].strip()
125
+ else:
126
+ origin = parts[0].capitalize()
127
+ destination = parts[-1].capitalize()
128
+
129
+ # Rufe MCP-Server auf
130
+ result = await mcp_client.search_connections(origin, destination)
131
+
132
+ if result:
133
+ # Formatiere Ergebnis als Markdown
134
+ response = f"## Zugverbindungen von {origin} nach {destination}\n\n"
135
+ response += result
136
+ return response
137
+ else:
138
+ return "Keine Verbindungen gefunden oder Fehler bei der Abfrage."
139
+
140
+ except Exception as e:
141
+ return f"Fehler bei der Suche: {str(e)}\n\nBitte versuchen Sie es erneut oder prüfen Sie Ihre Eingabe."
142
 
143
 
144
+ def search_train_connections(user_input: str):
145
+ """Synchrone Wrapper-Funktion für Gradio"""
146
  try:
147
+ # Erstelle neuen Event Loop für die asynchrone Funktion
148
+ loop = asyncio.new_event_loop()
149
+ asyncio.set_event_loop(loop)
150
+ result = loop.run_until_complete(search_train_connections_async(user_input))
151
+ loop.close()
152
+ return result, ""
153
  except Exception as e:
154
+ return f"Fehler: {str(e)}", ""
 
 
 
 
 
155
 
 
156
 
157
+ if __name__ == '__main__':
158
+ # Initialisiere MCP-Client beim Start
159
+ print("Initialisiere MCP-Client...")
160
+ try:
161
+ loop = asyncio.new_event_loop()
162
+ asyncio.set_event_loop(loop)
163
+ init_result = loop.run_until_complete(initialize_mcp_client())
164
+ print(init_result)
165
+ loop.close()
166
+ except Exception as e:
167
+ print(f"Warnung bei Initialisierung: {e}")
168
+ print("Client wird bei erster Anfrage initialisiert.")
169
+
170
+ # Gradio Interface
171
  with gr.Blocks() as demo:
172
+ title = gr.Markdown("# 🚂 Deutsche Bahn Zugverbindungen (MCP-Client)")
173
+ description = gr.Markdown("""
174
+ Geben Sie Start- und Zielort ein, um Zugverbindungen zu finden.
175
+
176
+ **Beispiele:**
177
+ - Frankfurt nach Berlin
178
+ - Von München nach Hamburg
179
+ - Köln Stuttgart
180
+ """)
181
+
182
  output_textbox = gr.Markdown()
183
+ input_textbox = gr.Textbox(
184
+ lines=2,
185
+ label="Ihre Anfrage",
186
+ placeholder="z.B. 'Frankfurt nach Berlin' oder 'Von München nach Hamburg'"
187
+ )
188
+ submit_button = gr.Button("🔍 Verbindungen suchen")
189
+
190
+ # Event Handler
191
+ submit_button.click(
192
+ fn=search_train_connections,
193
+ inputs=input_textbox,
194
+ outputs=[output_textbox, input_textbox]
195
+ )
196
+
197
+ # Enter-Taste funktioniert auch
198
+ input_textbox.submit(
199
+ fn=search_train_connections,
200
+ inputs=input_textbox,
201
+ outputs=[output_textbox, input_textbox]
202
+ )
203
+
204
+ demo.launch(show_error=True)