Denys Kanunnikov commited on
Commit
a4b9912
Β·
1 Parent(s): a0f810f

rename main files

Browse files
Files changed (2) hide show
  1. README.md +16 -16
  2. main.py +0 -356
README.md CHANGED
@@ -47,23 +47,23 @@ python -c "import nltk; nltk.download('punkt'); nltk.download('brown')"
47
 
48
  ### Run Tests
49
  ```bash
50
- python main.py --mode test
51
  ```
52
 
53
  ### Launch Web Interface
54
  ```bash
55
- python main.py --mode gradio
56
  ```
57
  Visit `http://localhost:7860` to access the web interface.
58
 
59
  ### Start MCP Server
60
  ```bash
61
- python main.py --mode mcp
62
  ```
63
 
64
  ### Combined Mode (Default)
65
  ```bash
66
- python main.py --mode combined
67
  ```
68
  Runs both MCP server and Gradio interface simultaneously.
69
 
@@ -73,18 +73,18 @@ Runs both MCP server and Gradio interface simultaneously.
73
 
74
  ```bash
75
  # Different execution modes
76
- python main.py --mode mcp # MCP server only
77
- python main.py --mode gradio # Web interface only
78
- python main.py --mode combined # Both services (default)
79
- python main.py --mode test # Run functionality tests
80
 
81
  # Gradio customization
82
- python main.py --mode gradio --port 8080 # Custom port
83
- python main.py --mode gradio --share # Enable public sharing
84
- python main.py --mode gradio --debug # Debug mode
85
 
86
  # Logging control
87
- python main.py --log-level DEBUG # Detailed logging
88
  ```
89
 
90
  ### Python API Usage
@@ -158,7 +158,7 @@ mcp-sentiment/
158
  β”‚ β”œβ”€β”€ tools.py # MCP tool definitions
159
  β”‚ └── gradio_interface.py # Web UI implementation
160
  β”œβ”€β”€ requirements.txt # Python dependencies
161
- β”œβ”€β”€ main.py # Application entry point
162
  └── README.md # This file
163
  ```
164
 
@@ -216,7 +216,7 @@ export TRANSFORMERS_CACHE=/path/to/cache
216
 
217
  ### Run All Tests
218
  ```bash
219
- python main.py --mode test
220
  ```
221
 
222
  ### Manual Testing
@@ -268,12 +268,12 @@ pip install gradio plotly pandas
268
 
269
  #### Port already in use
270
  ```bash
271
- python main.py --mode gradio --port 8080
272
  ```
273
 
274
  ### Debug Mode
275
  ```bash
276
- python main.py --mode combined --debug --log-level DEBUG
277
  ```
278
 
279
  ## πŸ”’ Security Considerations
 
47
 
48
  ### Run Tests
49
  ```bash
50
+ python app.py --mode test
51
  ```
52
 
53
  ### Launch Web Interface
54
  ```bash
55
+ python app.py --mode gradio
56
  ```
57
  Visit `http://localhost:7860` to access the web interface.
58
 
59
  ### Start MCP Server
60
  ```bash
61
+ python app.py --mode mcp
62
  ```
63
 
64
  ### Combined Mode (Default)
65
  ```bash
66
+ python app.py --mode combined
67
  ```
68
  Runs both MCP server and Gradio interface simultaneously.
69
 
 
73
 
74
  ```bash
75
  # Different execution modes
76
+ python app.py --mode mcp # MCP server only
77
+ python app.py --mode gradio # Web interface only
78
+ python app.py --mode combined # Both services (default)
79
+ python app.py --mode test # Run functionality tests
80
 
81
  # Gradio customization
82
+ python app.py --mode gradio --port 8080 # Custom port
83
+ python app.py --mode gradio --share # Enable public sharing
84
+ python app.py --mode gradio --debug # Debug mode
85
 
86
  # Logging control
87
+ python app.py --log-level DEBUG # Detailed logging
88
  ```
89
 
90
  ### Python API Usage
 
158
  β”‚ β”œβ”€β”€ tools.py # MCP tool definitions
159
  β”‚ └── gradio_interface.py # Web UI implementation
160
  β”œβ”€β”€ requirements.txt # Python dependencies
161
+ β”œβ”€β”€ app.py # Application entry point
162
  └── README.md # This file
163
  ```
164
 
 
216
 
217
  ### Run All Tests
218
  ```bash
219
+ python app.py --mode test
220
  ```
221
 
222
  ### Manual Testing
 
268
 
269
  #### Port already in use
270
  ```bash
271
+ python app.py --mode gradio --port 8080
272
  ```
273
 
274
  ### Debug Mode
275
  ```bash
276
+ python app.py --mode combined --debug --log-level DEBUG
277
  ```
278
 
279
  ## πŸ”’ Security Considerations
main.py DELETED
@@ -1,356 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Main entry point for MCP Sentiment Analysis Server.
4
-
5
- This script provides multiple modes of operation:
6
- 1. MCP Server mode - JSON-RPC 2.0 server for AI model integration
7
- 2. Gradio Interface mode - Web UI for human interaction
8
- 3. Combined mode - Both MCP server and Gradio interface
9
- 4. Test mode - Run basic functionality tests
10
-
11
- Usage:
12
- python main.py --mode mcp # Run MCP server only
13
- python main.py --mode gradio # Run Gradio interface only
14
- python main.py --mode combined # Run both (default)
15
- python main.py --mode test # Run tests
16
- """
17
-
18
- import asyncio
19
- import argparse
20
- import logging
21
- import sys
22
- import signal
23
- import threading
24
- from typing import Optional
25
- from concurrent.futures import ThreadPoolExecutor
26
-
27
- try:
28
- import uvloop
29
- UVLOOP_AVAILABLE = True
30
- except ImportError:
31
- UVLOOP_AVAILABLE = False
32
-
33
- from src import (
34
- create_server,
35
- MCPServerRunner,
36
- create_gradio_interface,
37
- get_analyzer
38
- )
39
-
40
-
41
- class ApplicationRunner:
42
- """
43
- Main application runner that manages different execution modes.
44
-
45
- Supports running MCP server, Gradio interface, or both simultaneously
46
- with proper resource management and graceful shutdown.
47
- """
48
-
49
- def __init__(self):
50
- """Initialize application runner."""
51
- self.logger = logging.getLogger(__name__)
52
- self.mcp_server = None
53
- self.gradio_interface = None
54
- self.running = False
55
- self.executor = ThreadPoolExecutor(max_workers=2)
56
-
57
- # Setup signal handlers
58
- signal.signal(signal.SIGINT, self._signal_handler)
59
- signal.signal(signal.SIGTERM, self._signal_handler)
60
-
61
- def _signal_handler(self, signum, frame):
62
- """Handle shutdown signals."""
63
- self.logger.info(f"Received signal {signum}, shutting down...")
64
- self.running = False
65
-
66
- async def run_mcp_server(self) -> None:
67
- """Run MCP server only."""
68
- self.logger.info("Starting MCP server mode")
69
-
70
- try:
71
- # Create and run MCP server
72
- self.mcp_server = await create_server()
73
- runner = MCPServerRunner(self.mcp_server)
74
-
75
- self.running = True
76
- await runner.run()
77
-
78
- except Exception as e:
79
- self.logger.error(f"MCP server failed: {e}")
80
- raise
81
- finally:
82
- if self.mcp_server:
83
- await self.mcp_server.stop()
84
-
85
- def run_gradio_interface(self, **kwargs) -> None:
86
- """Run Gradio interface only."""
87
- self.logger.info("Starting Gradio interface mode")
88
-
89
- try:
90
- # Create and launch Gradio interface
91
- self.gradio_interface = create_gradio_interface()
92
-
93
- # Default launch parameters
94
- launch_params = {
95
- "server_name": "0.0.0.0",
96
- "server_port": 7860,
97
- "share": False,
98
- "debug": False,
99
- "show_error": True,
100
- "quiet": False
101
- }
102
- launch_params.update(kwargs)
103
-
104
- self.running = True
105
- self.gradio_interface.launch(**launch_params)
106
-
107
- except Exception as e:
108
- self.logger.error(f"Gradio interface failed: {e}")
109
- raise
110
-
111
- async def run_combined(self, **gradio_kwargs) -> None:
112
- """Run both MCP server and Gradio interface."""
113
- self.logger.info("Starting combined mode (MCP server + Gradio interface)")
114
-
115
- try:
116
- # Create MCP server
117
- self.mcp_server = await create_server()
118
-
119
- # Create Gradio interface
120
- self.gradio_interface = create_gradio_interface()
121
-
122
- # Default Gradio launch parameters
123
- launch_params = {
124
- "server_name": "0.0.0.0",
125
- "server_port": 7860,
126
- "share": False,
127
- "debug": False,
128
- "show_error": True,
129
- "quiet": False
130
- }
131
- launch_params.update(gradio_kwargs)
132
-
133
- self.running = True
134
-
135
- # Run Gradio in thread pool
136
- gradio_future = self.executor.submit(
137
- self.gradio_interface.launch, **launch_params
138
- )
139
-
140
- # Run MCP server in main thread
141
- runner = MCPServerRunner(self.mcp_server)
142
-
143
- # Start both services
144
- self.logger.info("Both services starting...")
145
-
146
- # Wait for either to complete or fail
147
- try:
148
- await runner.run()
149
- except Exception as e:
150
- self.logger.error(f"MCP server error: {e}")
151
- raise
152
- finally:
153
- # Cleanup
154
- if gradio_future:
155
- gradio_future.cancel()
156
-
157
- except Exception as e:
158
- self.logger.error(f"Combined mode failed: {e}")
159
- raise
160
- finally:
161
- if self.mcp_server:
162
- await self.mcp_server.stop()
163
-
164
- async def run_tests(self) -> bool:
165
- """Run basic functionality tests."""
166
- self.logger.info("Running functionality tests...")
167
-
168
- try:
169
- # Test 1: Sentiment analyzer initialization
170
- self.logger.info("Test 1: Initializing sentiment analyzer...")
171
- analyzer = await get_analyzer("textblob")
172
- self.logger.info(f"βœ“ Analyzer initialized with backend: {analyzer.backend}")
173
-
174
- # Test 2: Basic sentiment analysis
175
- self.logger.info("Test 2: Basic sentiment analysis...")
176
- test_texts = [
177
- "I love this product!",
178
- "This is terrible.",
179
- "It's okay, nothing special."
180
- ]
181
-
182
- for text in test_texts:
183
- result = await analyzer.analyze(text)
184
- self.logger.info(f"βœ“ '{text}' -> {result.label.value} ({result.confidence:.2f})")
185
-
186
- # Test 3: Batch analysis
187
- self.logger.info("Test 3: Batch analysis...")
188
- batch_results = await analyzer.analyze_batch(test_texts)
189
- self.logger.info(f"βœ“ Batch analysis completed: {len(batch_results)} results")
190
-
191
- # Test 4: MCP tools
192
- self.logger.info("Test 4: MCP tools...")
193
- from src.tools import get_tools
194
- tools = get_tools()
195
- available_tools = tools.get_tools()
196
- self.logger.info(f"βœ“ {len(available_tools)} MCP tools available")
197
-
198
- # Test 5: Tool execution
199
- self.logger.info("Test 5: Tool execution...")
200
- result = await tools.call_tool("analyze_sentiment", {
201
- "text": "This is a test message",
202
- "backend": "textblob"
203
- })
204
- self.logger.info(f"βœ“ Tool execution successful: {result.get('success', False)}")
205
-
206
- # Test 6: Health check
207
- self.logger.info("Test 6: Health check...")
208
- health_result = await tools.call_tool("health_check", {})
209
- self.logger.info(f"βœ“ Health check: {health_result.get('status', 'unknown')}")
210
-
211
- # Cleanup
212
- await analyzer.cleanup()
213
-
214
- self.logger.info("πŸŽ‰ All tests passed!")
215
- return True
216
-
217
- except Exception as e:
218
- self.logger.error(f"❌ Test failed: {e}")
219
- return False
220
-
221
-
222
- def setup_logging(level: str = "INFO") -> None:
223
- """
224
- Setup logging configuration.
225
-
226
- Args:
227
- level: Logging level
228
- """
229
- logging.basicConfig(
230
- level=getattr(logging, level.upper()),
231
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
232
- handlers=[
233
- logging.StreamHandler(sys.stderr)
234
- ]
235
- )
236
-
237
-
238
- def parse_arguments() -> argparse.Namespace:
239
- """
240
- Parse command line arguments.
241
-
242
- Returns:
243
- Parsed arguments
244
- """
245
- parser = argparse.ArgumentParser(
246
- description="MCP Sentiment Analysis Server",
247
- formatter_class=argparse.RawDescriptionHelpFormatter,
248
- epilog="""
249
- Examples:
250
- python main.py --mode mcp # MCP server only
251
- python main.py --mode gradio # Gradio interface only
252
- python main.py --mode combined # Both services
253
- python main.py --mode test # Run tests
254
- python main.py --mode gradio --port 8080 # Custom port
255
- python main.py --mode gradio --share # Public sharing
256
- """
257
- )
258
-
259
- parser.add_argument(
260
- "--mode",
261
- choices=["mcp", "gradio", "combined", "test"],
262
- default="combined",
263
- help="Execution mode (default: combined)"
264
- )
265
-
266
- parser.add_argument(
267
- "--log-level",
268
- choices=["DEBUG", "INFO", "WARNING", "ERROR"],
269
- default="INFO",
270
- help="Logging level (default: INFO)"
271
- )
272
-
273
- # Gradio-specific options
274
- parser.add_argument(
275
- "--port",
276
- type=int,
277
- default=7860,
278
- help="Gradio server port (default: 7860)"
279
- )
280
-
281
- parser.add_argument(
282
- "--host",
283
- default="0.0.0.0",
284
- help="Gradio server host (default: 0.0.0.0)"
285
- )
286
-
287
- parser.add_argument(
288
- "--share",
289
- action="store_true",
290
- help="Enable Gradio public sharing"
291
- )
292
-
293
- parser.add_argument(
294
- "--debug",
295
- action="store_true",
296
- help="Enable debug mode"
297
- )
298
-
299
- return parser.parse_args()
300
-
301
-
302
- async def main() -> None:
303
- """Main application entry point."""
304
- # Parse arguments
305
- args = parse_arguments()
306
-
307
- # Setup logging
308
- setup_logging(args.log_level)
309
- logger = logging.getLogger(__name__)
310
-
311
- # Use uvloop if available for better performance
312
- if UVLOOP_AVAILABLE and args.mode in ["mcp", "combined"]:
313
- asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
314
- logger.info("Using uvloop for better performance")
315
-
316
- # Create application runner
317
- runner = ApplicationRunner()
318
-
319
- try:
320
- if args.mode == "mcp":
321
- await runner.run_mcp_server()
322
-
323
- elif args.mode == "gradio":
324
- # Gradio runs in sync mode
325
- gradio_kwargs = {
326
- "server_name": args.host,
327
- "server_port": args.port,
328
- "share": args.share,
329
- "debug": args.debug
330
- }
331
- runner.run_gradio_interface(**gradio_kwargs)
332
-
333
- elif args.mode == "combined":
334
- gradio_kwargs = {
335
- "server_name": args.host,
336
- "server_port": args.port,
337
- "share": args.share,
338
- "debug": args.debug
339
- }
340
- await runner.run_combined(**gradio_kwargs)
341
-
342
- elif args.mode == "test":
343
- success = await runner.run_tests()
344
- sys.exit(0 if success else 1)
345
-
346
- except KeyboardInterrupt:
347
- logger.info("Application interrupted by user")
348
- except Exception as e:
349
- logger.error(f"Application error: {e}")
350
- sys.exit(1)
351
- finally:
352
- logger.info("Application shutdown complete")
353
-
354
-
355
- if __name__ == "__main__":
356
- asyncio.run(main())