judith.ibanez commited on
Commit
3697654
·
1 Parent(s): 2962bd1
Files changed (3) hide show
  1. Dockerfile +1 -1
  2. README.md +2 -0
  3. app.py +19 -263
Dockerfile CHANGED
@@ -42,4 +42,4 @@ RUN apt-get clean
42
  COPY app.py /app/app.py
43
  WORKDIR /app
44
 
45
- CMD ["python3", "app.py"]
 
42
  COPY app.py /app/app.py
43
  WORKDIR /app
44
 
45
+ CMD ["python3", "app.py"]
README.md CHANGED
@@ -10,6 +10,8 @@ pinned: false
10
  license: apache-2.0
11
  short_description: Analyze music scores from PDF files
12
  app_port: 7860
 
 
13
  ---
14
 
15
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
10
  license: apache-2.0
11
  short_description: Analyze music scores from PDF files
12
  app_port: 7860
13
+ tags:
14
+ - mcp-server-track
15
  ---
16
 
17
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -1,281 +1,37 @@
1
  import gradio as gr
 
2
  import os
3
- import shutil
4
- import tempfile
5
- import threading
6
- import http.server
7
- import socketserver
8
- from urllib.parse import urljoin
9
- import time
10
-
11
- # Global variable to store the HTTP server
12
- file_server = None
13
- server_port = 8000
14
-
15
- def start_file_server(directory, port=8000):
16
- """Start a simple HTTP server to serve files"""
17
- global file_server
18
-
19
- class Handler(http.server.SimpleHTTPRequestHandler):
20
- def __init__(self, *args, **kwargs):
21
- super().__init__(*args, directory=directory, **kwargs)
22
-
23
- try:
24
- file_server = socketserver.TCPServer(("", port), Handler)
25
- server_thread = threading.Thread(target=file_server.serve_forever, daemon=True)
26
- server_thread.start()
27
- return f"http://localhost:{port}"
28
- except Exception as e:
29
- print(f"Error starting file server: {e}")
30
- return None
31
 
32
  def recognize_music(pdf_file):
33
- """Converts a PDF file to a Music score using MCP Audiveris
34
 
35
  Args:
36
  pdf_file: the file with the PDF file
37
 
38
  Returns:
39
- the result from MCP Audiveris conversion
40
- """
41
- if pdf_file is None:
42
- return "No file uploaded"
43
-
44
- try:
45
- # Get the file path
46
- pdf_file_path = pdf_file.name if hasattr(pdf_file, 'name') else str(pdf_file)
47
-
48
- # Create a temporary directory for serving the file
49
- temp_dir = tempfile.mkdtemp()
50
-
51
- # Copy the file to the temporary directory with a simple name
52
- temp_pdf_name = "input.pdf"
53
- temp_pdf_path = os.path.join(temp_dir, temp_pdf_name)
54
- shutil.copy2(pdf_file_path, temp_pdf_path)
55
-
56
- # Start a simple HTTP server to serve the file
57
- server_url = start_file_server(temp_dir, server_port)
58
- if not server_url:
59
- return "Error: Could not start file server"
60
-
61
- # Create the URL for the PDF file
62
- pdf_url = f"{server_url}/{temp_pdf_name}"
63
-
64
- # Wait a moment for the server to be ready
65
- time.sleep(0.5)
66
-
67
- # Now we can use the MCP Audiveris function with the URL
68
- # Note: This is where you would call the MCP function
69
- # For now, I'll show how it would be called:
70
-
71
- # Example of how to call MCP Audiveris (uncomment when ready to use):
72
- # from mcp_audiveris import convert_and_display
73
- # result = convert_and_display(pdf_url)
74
- # return result
75
-
76
- # For now, let's fall back to local processing
77
- audiveris = "/opt/audiveris/bin/Audiveris"
78
- output_dir = temp_dir
79
- pdf_file_name = os.path.basename(pdf_file_path)
80
- musicXml_file_name = os.path.splitext(pdf_file_name)[0]+".mxl"
81
- output_file = os.path.join(output_dir, musicXml_file_name)
82
-
83
- import subprocess
84
- cmd = [
85
- audiveris, "-batch", "-export", "-output", output_dir, temp_pdf_path
86
- ]
87
-
88
- result = subprocess.run(cmd, capture_output=True, text=True)
89
-
90
- print(f"Done. Music score file saved to {output_file}\n\n{result.stdout}\n{result.stderr}")
91
- print(f"PDF was served at: {pdf_url}")
92
-
93
- if os.path.exists(output_file):
94
- return output_file
95
- else:
96
- return f"Error: Output file not created. {result.stderr}"
97
-
98
- except Exception as e:
99
- return f"Error processing file: {str(e)}"
100
-
101
- # Alternative function that directly uses MCP Audiveris
102
- def recognize_music_mcp(pdf_file):
103
- """Converts a PDF file using MCP Audiveris directly"""
104
- if pdf_file is None:
105
- return "No file uploaded"
106
-
107
- try:
108
- # For MCP Audiveris, we need a URL
109
- # If you have the file hosted somewhere, use that URL
110
- # For local files, you'd need to upload them to a temporary hosting service
111
-
112
- # This is a placeholder - you would need to implement file hosting
113
- # or use a service like temporary file hosting
114
- return "MCP Audiveris requires a URL. Please host your PDF file online and provide the URL."
115
-
116
- except Exception as e:
117
- return f"Error: {str(e)}"
118
-
119
- def recognize_music_from_url(pdf_url):
120
- """Converts a PDF file to a Music score using MCP Audiveris
121
-
122
- Args:
123
- pdf_url: URL to the PDF file (must be http:// or https://)
124
-
125
- Returns:
126
- the result from MCP Audiveris conversion
127
  """
128
- if not pdf_url:
129
- return "Please provide a PDF URL"
130
-
131
- if not (pdf_url.startswith('http://') or pdf_url.startswith('https://')):
132
- return "Error: URL must start with http:// or https://"
133
-
134
- # For now, this function serves as a placeholder for MCP integration
135
- # When this Gradio app is used as an MCP server, this function will be exposed
136
- # as an MCP tool that can be called by MCP clients
137
-
138
- return f"✅ URL validated: {pdf_url}\n\n📋 This function is ready for MCP integration.\n\nWhen called via MCP client, it will:\n1. Receive the PDF URL\n2. Process it with Audiveris\n3. Return the MusicXML result\n\n🔧 To actually process the PDF, call this function through an MCP client that has access to the Audiveris conversion tools."
139
 
140
- def recognize_music_local(pdf_file):
141
- """Converts a local PDF file using local Audiveris installation"""
142
- if pdf_file is None:
143
- return "No file uploaded"
144
-
145
- # Handle MCP document references
146
- if isinstance(pdf_file, str) and pdf_file.startswith('file://'):
147
- return f"Invalid file data format, provide a url ('http://...' or 'https://...'). Received: {pdf_file}"
148
-
149
- try:
150
- import subprocess
151
- import os
152
- import tempfile
153
- import shutil
154
-
155
- # Get the file path
156
- pdf_file_path = pdf_file.name if hasattr(pdf_file, 'name') else str(pdf_file)
157
-
158
- # Create a temporary directory for output
159
- temp_dir = tempfile.mkdtemp()
160
-
161
- # Copy the file to the temporary directory
162
- temp_pdf_path = os.path.join(temp_dir, "input.pdf")
163
- shutil.copy2(pdf_file_path, temp_pdf_path)
164
-
165
- # Use local Audiveris
166
- audiveris = "/opt/audiveris/bin/Audiveris"
167
- output_dir = temp_dir
168
- pdf_file_name = os.path.basename(pdf_file_path)
169
- musicXml_file_name = os.path.splitext(pdf_file_name)[0]+".mxl"
170
- output_file = os.path.join(output_dir, musicXml_file_name)
171
-
172
- cmd = [
173
- audiveris, "-batch", "-export", "-output", output_dir, temp_pdf_path
174
- ]
175
-
176
- result = subprocess.run(cmd, capture_output=True, text=True)
177
 
178
- print(f"Done. Music score file saved to {output_file}\n\n{result.stdout}\n{result.stderr}")
179
-
180
- if os.path.exists(output_file):
181
- return output_file
182
- else:
183
- return f"Error: Output file not created. {result.stderr}"
184
-
185
- except Exception as e:
186
- return f"Error processing file: {str(e)}"
187
-
188
- def recognize_music_with_file_server(pdf_file):
189
- """Converts a local PDF file by serving it via HTTP and using MCP Audiveris"""
190
- if pdf_file is None:
191
- return "No file uploaded"
192
-
193
- # Handle MCP document references
194
- if isinstance(pdf_file, str) and pdf_file.startswith('file://'):
195
- return f"Invalid file data format, provide a url ('http://...' or 'https://...'). Received: {pdf_file}"
196
-
197
- try:
198
- import tempfile
199
- import shutil
200
- import threading
201
- import http.server
202
- import socketserver
203
- import time
204
- import os
205
-
206
- # Get the file path
207
- pdf_file_path = pdf_file.name if hasattr(pdf_file, 'name') else str(pdf_file)
208
-
209
- # Create a temporary directory for serving the file
210
- temp_dir = tempfile.mkdtemp()
211
-
212
- # Copy the file to the temporary directory with a simple name
213
- temp_pdf_name = "input.pdf"
214
- temp_pdf_path = os.path.join(temp_dir, temp_pdf_name)
215
- shutil.copy2(pdf_file_path, temp_pdf_path)
216
-
217
- # Start a simple HTTP server to serve the file
218
- server_port = 8000
219
-
220
- class Handler(http.server.SimpleHTTPRequestHandler):
221
- def __init__(self, *args, **kwargs):
222
- super().__init__(*args, directory=temp_dir, **kwargs)
223
-
224
- try:
225
- file_server = socketserver.TCPServer(("", server_port), Handler)
226
- server_thread = threading.Thread(target=file_server.serve_forever, daemon=True)
227
- server_thread.start()
228
- server_url = f"http://localhost:{server_port}"
229
- except Exception as e:
230
- return f"Error starting file server: {e}"
231
-
232
- # Create the URL for the PDF file
233
- pdf_url = f"{server_url}/{temp_pdf_name}"
234
-
235
- # Wait a moment for the server to be ready
236
- time.sleep(0.5)
237
-
238
- # Call the MCP Audiveris function
239
- result = mcp_audiveris_convert_and_display(pdf_url)
240
-
241
- # Stop the server
242
- file_server.shutdown()
243
-
244
- return result
245
-
246
- except Exception as e:
247
- return f"Error processing file: {str(e)}"
248
 
249
- # Create three interfaces
250
- url_interface = gr.Interface(
251
- fn=recognize_music_from_url,
252
- inputs=gr.Textbox(label="PDF URL (http:// or https://)", placeholder="https://example.com/music-score.pdf"),
253
- outputs=gr.Textbox(label="Result"),
254
- description="Enter a URL to a PDF music score to process with MCP Audiveris.",
255
- title="URL Input (MCP)"
256
- )
257
 
258
- file_mcp_interface = gr.Interface(
259
- fn=recognize_music_with_file_server,
260
- inputs=gr.File(file_types=[".pdf"], label="Upload PDF music score"),
261
- outputs=gr.Textbox(label="Result"),
262
- description="Upload a PDF music score and process it with MCP Audiveris (via temporary file server). Note: MCP tools require URLs, not file uploads.",
263
- title="File Upload (MCP)"
264
- )
265
 
266
- file_local_interface = gr.Interface(
267
- fn=recognize_music_local,
268
  inputs=gr.File(file_types=[".pdf"], label="Upload PDF music score"),
269
  outputs=gr.File(label="Download MusicXML file"),
270
- description="Upload a PDF music score and create a MusicXML file using local Audiveris. Note: MCP tools require URLs, not file uploads.",
271
- title="File Upload (Local)"
272
  )
273
-
274
- # Combine all interfaces in a tabbed interface
275
- demo = gr.TabbedInterface(
276
- [url_interface, file_mcp_interface, file_local_interface],
277
- ["URL Input (MCP)", "File Upload (MCP)", "File Upload (Local)"]
278
- )
279
-
280
- if __name__ == "__main__":
281
- demo.launch(server_name="0.0.0.0", server_port=7860, share=True, mcp_server=True)
 
1
  import gradio as gr
2
+ import subprocess
3
  import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  def recognize_music(pdf_file):
6
+ """Converts a PDF file to a Music score
7
 
8
  Args:
9
  pdf_file: the file with the PDF file
10
 
11
  Returns:
12
+ the path were the MusicXML file is generated
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  """
14
+ audiveris = "/opt/audiveris/bin/Audiveris"
15
+ output_dir = "/tmp/output"
16
+ pdf_file_path = pdf_file.name
17
+ pdf_file_name = os.path.basename(pdf_file.name)
18
+ musicXml_file_name = os.path.splitext(pdf_file_name)[0]+".mxl"
19
+ output_file = output_dir + "/" + musicXml_file_name
 
 
 
 
 
20
 
21
+ cmd = [
22
+ audiveris, "-batch", "-export", "-output", output_dir, pdf_file_path
23
+ ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ result = subprocess.run(cmd, capture_output=True, text=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ print (f"Done. Music score file saved to {output_file}\n\n{result.stdout}\n{result.stderr}")
 
 
 
 
 
 
 
28
 
29
+ return output_file
 
 
 
 
 
 
30
 
31
+ audiveris = gr.Interface(
32
+ fn=recognize_music,
33
  inputs=gr.File(file_types=[".pdf"], label="Upload PDF music score"),
34
  outputs=gr.File(label="Download MusicXML file"),
35
+ description="Upload a PDF music socre and create a MusicXML file from it.",
 
36
  )
37
+ audiveris.launch(server_name="0.0.0.0", server_port=7860, share=True, mcp_server=True)