judith.ibanez commited on
Commit
ccc3879
·
1 Parent(s): 542f57d

is working

Browse files
Files changed (3) hide show
  1. Dockerfile +75 -0
  2. README copy.md +62 -0
  3. app.py +84 -0
Dockerfile ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM ubuntu:24.04
2
+
3
+ ENV DEBIAN_FRONTEND=noninteractive
4
+
5
+ ## Install dependencies
6
+ RUN apt-get update && \
7
+ # Enable all necessary Ubuntu repositories
8
+ sed -i 's/^# deb /deb /g' /etc/apt/sources.list && \
9
+ sed -i 's/restricted/restricted universe multiverse/g' /etc/apt/sources.list && \
10
+ apt-get update && \
11
+ apt-get install -y --no-install-recommends \
12
+ wget \
13
+ unzip \
14
+ python3 \
15
+ python3-pip \
16
+ # Audio and GUI libraries needed by Audiveris (using correct Ubuntu 24.04 package names)
17
+ libasound2t64 \
18
+ libbsd0 \
19
+ libx11-6 \
20
+ libxau6 \
21
+ libxcb1 \
22
+ libxdmcp6 \
23
+ libxext6 \
24
+ libxi6 \
25
+ libxrender1 \
26
+ libxtst6 \
27
+ xdg-utils \
28
+ fontconfig \
29
+ fonts-dejavu-core \
30
+ fonts-freefont-ttf \
31
+ fonts-liberation \
32
+ && apt-get clean \
33
+ && rm -rf /var/lib/apt/lists/*
34
+
35
+ ## Download, patch and install Audiveris for headless use
36
+ RUN export AUDIVERIS_URL="https://github.com/Audiveris/audiveris/releases/download/5.6.1/Audiveris-5.6.1-ubuntu24.04-x86_64.deb" && \
37
+ export DEB_FILE=$(basename ${AUDIVERIS_URL}) && \
38
+ \
39
+ # Download the package
40
+ wget ${AUDIVERIS_URL} && \
41
+ \
42
+ # Unpack the debian package to a temporary directory
43
+ dpkg-deb -R ${DEB_FILE} /tmp/audiveris && \
44
+ \
45
+ # Disable the post-installation script to prevent GUI-related actions.
46
+ # A simple script that exits successfully is used as a replacement.
47
+ echo -e '#!/bin/sh\nexit 0' > /tmp/audiveris/DEBIAN/postinst && \
48
+ chmod +x /tmp/audiveris/DEBIAN/postinst && \
49
+ \
50
+ # Repackage the modified components into a new .deb file.
51
+ dpkg-deb -b /tmp/audiveris /tmp/audiveris-fixed.deb && \
52
+ \
53
+ # Update lists and then install the patched package.
54
+ # dpkg will likely fail due to missing dependencies, which apt-get -f will then fix.
55
+ apt-get update && \
56
+ dpkg -i /tmp/audiveris-fixed.deb || apt-get -f install -y && \
57
+ \
58
+ # Clean up downloaded and temporary files
59
+ rm ${DEB_FILE} && \
60
+ rm -rf /tmp/audiveris /tmp/audiveris-fixed.deb && \
61
+ apt-get autoremove -y && \
62
+ apt-get clean && \
63
+ rm -rf /var/lib/apt/lists/*
64
+
65
+ ## Install Gradio MCP
66
+ # TODO: use a python virtual environment
67
+ RUN pip install --break-system-packages gradio[mcp]
68
+
69
+ ## Copy MCP server and execute it
70
+ COPY app.py /app/app.py
71
+ WORKDIR /app
72
+
73
+ CMD ["python3", "-u", "app.py"]
74
+
75
+ RUN find / -name Audiveris || true
README copy.md ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Gradio APP Hackathon - score
3
+ emoji: 🎶
4
+ colorFrom: yellow
5
+ colorTo: red
6
+ sdk: gradio
7
+ sdk_version: 5.32.1
8
+ app_file: app.py
9
+ pinned: false
10
+ ---
11
+
12
+ Check out the configuration reference at <https://huggingface.co/docs/hub/spaces-config-reference>
13
+
14
+ ## 🚀 How to Build and Run the MCP Audiveris Server
15
+
16
+ ### 🐳 Build the Docker Image
17
+
18
+ ```bash
19
+ docker buildx build --load --platform linux/amd64 -t mcp-server-audiveris .
20
+ ```
21
+
22
+ ### ▶️ Run the Container
23
+
24
+ ```bash
25
+ docker run --platform linux/amd64 -p 7860:7860 mcp-server-audiveris
26
+ ```
27
+
28
+ The Gradio web interface will be available at: [http://localhost:7860](http://localhost:7860)
29
+
30
+ ---
31
+
32
+ ## 🎼 How to Use
33
+
34
+ 1. **Upload a PDF**: Click the "Upload PDF music score" button and select your music score in PDF format.
35
+ 2. **Convert**: The server will process the PDF and generate a MusicXML file in `.mxl` format.
36
+ 3. **Download**: Once finished, click "Download MusicXML file" to get your `.mxl` file.
37
+
38
+ ---
39
+
40
+ ## 📦 What is the MXL Format?
41
+
42
+ - `.mxl` is a compressed (ZIP) version of MusicXML, used for sharing digital sheet music.
43
+ - You can open `.mxl` files with music notation software like MuseScore, Finale, or Sibelius.
44
+ - To inspect the contents, rename `.mxl` to `.zip` and extract it. You should see at least one `.xml` file inside.
45
+
46
+ **Example structure:**
47
+
48
+ ```sh
49
+ my_score.mxl
50
+ ├── META-INF/
51
+ │ └── container.xml
52
+ └── my_score.xml
53
+ ```
54
+
55
+ ---
56
+
57
+ ## 🛠️ Troubleshooting
58
+
59
+ - If you get errors about missing fonts, make sure the Docker image includes `fontconfig` and common font packages.
60
+ - If no output file is generated, check that your PDF contains clear, printable music notation.
61
+
62
+ ---
app.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/Audiveris"
15
+ output_dir = "/tmp/output"
16
+ gradio_tmp_dir = os.path.dirname(pdf_file.name)
17
+
18
+ # Create output directory if it doesn't exist
19
+ os.makedirs(output_dir, exist_ok=True)
20
+
21
+ pdf_file_path = pdf_file.name
22
+ pdf_file_name = os.path.basename(pdf_file.name)
23
+ musicXml_file_name = os.path.splitext(pdf_file_name)[0]+".mxl"
24
+ output_file = output_dir + "/" + musicXml_file_name
25
+
26
+ cmd = [
27
+ audiveris, "-batch", "-export", "-output", output_dir, pdf_file_path
28
+ ]
29
+
30
+ try:
31
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
32
+
33
+ print(f"Audiveris command: {' '.join(cmd)}")
34
+ print(f"Return code: {result.returncode}")
35
+ print(f"STDOUT: {result.stdout}")
36
+ print(f"STDERR: {result.stderr}")
37
+
38
+ # List files in output and gradio temp dir for debugging
39
+ if os.path.exists(output_dir):
40
+ files_in_output = os.listdir(output_dir)
41
+ print(f"Files in /tmp/output: {files_in_output}")
42
+ if os.path.exists(gradio_tmp_dir):
43
+ files_in_gradio = os.listdir(gradio_tmp_dir)
44
+ print(f"Files in {gradio_tmp_dir}: {files_in_gradio}")
45
+
46
+ # Check if the expected file exists
47
+ if os.path.exists(output_file):
48
+ print(f"Success! Music score file saved to {output_file}")
49
+ return output_file
50
+ else:
51
+ # Try different possible extensions/names
52
+ possible_files = []
53
+ base_name = os.path.splitext(pdf_file_name)[0]
54
+
55
+ # Check for different extensions
56
+ for ext in [".mxl", ".xml", ".musicxml"]:
57
+ possible_file = os.path.join(output_dir, base_name + ext)
58
+ if os.path.exists(possible_file):
59
+ print(f"Found file with different extension: {possible_file}")
60
+ return possible_file
61
+ possible_files.append(possible_file)
62
+
63
+ error_msg = (
64
+ f"No output file found. Expected: {output_file}\n"
65
+ f"Tried: {possible_files}\n"
66
+ f"Command output (stdout):\n{result.stdout}\n"
67
+ f"Command errors (stderr):\n{result.stderr}\n"
68
+ f"Files in /tmp/output: {files_in_output if 'files_in_output' in locals() else 'N/A'}\n"
69
+ f"Files in {gradio_tmp_dir}: {files_in_gradio if 'files_in_gradio' in locals() else 'N/A'}\n"
70
+ )
71
+ raise FileNotFoundError(error_msg)
72
+ except subprocess.TimeoutExpired:
73
+ raise Exception("Audiveris process timed out after 300 seconds")
74
+ except Exception as e:
75
+ raise Exception(f"Error processing file: {str(e)}")
76
+
77
+ audiveris = gr.Interface(
78
+ fn=recognize_music,
79
+ inputs=gr.File(file_types=[".pdf"], label="Upload PDF music score"),
80
+ outputs=gr.File(label="Download MusicXML file"),
81
+ description="Upload a PDF music socre and create a MusicXML file from it.",
82
+ )
83
+
84
+ audiveris.launch(server_name="0.0.0.0", mcp_server=True, ssr_mode=False)