peter288 commited on
Commit
9804e6d
·
verified ·
1 Parent(s): 4aa7abe

Upload 4 files

Browse files
Files changed (4) hide show
  1. Dockerfile +20 -0
  2. app.py +56 -0
  3. midi_utils.py +19 -0
  4. requirements.txt +4 -0
Dockerfile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 使用一个轻量级的 Python 官方镜像
2
+ FROM python:3.10-slim
3
+
4
+ # 设置工作目录
5
+ WORKDIR /code
6
+
7
+ # 复制依赖文件并安装依赖
8
+ COPY ./requirements.txt /code/requirements.txt
9
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
10
+
11
+ # 复制所有应用代码到工作目录
12
+ COPY ./app.py /code/app.py
13
+ COPY ./midi_utils.py /code/midi_utils.py
14
+
15
+ # 暴露 Hugging Face Spaces 期望的端口 7860
16
+ EXPOSE 7860
17
+
18
+ # 启动 Uvicorn 服务器,并添加 --proxy-headers 标志
19
+ # 这是解决 /docs 404 问题的关键
20
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860", "--proxy-headers"]
app.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from fastapi.responses import StreamingResponse, JSONResponse
4
+ from midi_utils import process_midi
5
+
6
+ # We no longer need os or ROOT_PATH here, keeping the code clean.
7
+ # Uvicorn with --proxy-headers will handle the path prefix automatically.
8
+ app = FastAPI(
9
+ title="MIDI Processor API",
10
+ description="A pure API backend to process MIDI files, running correctly behind a proxy.",
11
+ version="1.0.2", # Version updated for the final fix
12
+ )
13
+
14
+ # --- CORS Middleware (no change) ---
15
+ origins = ["*"]
16
+ app.add_middleware(
17
+ CORSMiddleware,
18
+ allow_origins=origins,
19
+ allow_credentials=True,
20
+ allow_methods=["*"],
21
+ allow_headers=["*"],
22
+ )
23
+
24
+ # --- API Endpoints (no change) ---
25
+
26
+ @app.get("/", tags=["General"])
27
+ def read_root():
28
+ # The /docs link will now work correctly without us manually building the path.
29
+ return {
30
+ "message": "Welcome to the MIDI Processor API!",
31
+ "status": "ok",
32
+ "documentation_url": "/docs" # FastAPI will resolve this correctly now
33
+ }
34
+
35
+ @app.post("/process-midi", tags=["MIDI Processing"])
36
+ async def process_midi_file(file: UploadFile = File(..., description="The MIDI file (.mid, .midi) to be processed.")):
37
+ if not file.filename.lower().endswith(('.mid', '.midi')):
38
+ return JSONResponse(
39
+ status_code=400,
40
+ content={"error": "Invalid file type. Please upload a .mid or .midi file."}
41
+ )
42
+ try:
43
+ print(f"Processing file: {file.filename}")
44
+ midi_data = await file.read()
45
+ processed_data_buffer = process_midi(midi_data)
46
+ return StreamingResponse(
47
+ processed_data_buffer,
48
+ media_type="audio/midi",
49
+ headers={"Content-Disposition": f"attachment; filename=processed_{file.filename}"}
50
+ )
51
+ except Exception as e:
52
+ print(f"An error occurred while processing the file: {e}")
53
+ return JSONResponse(
54
+ status_code=500,
55
+ content={"error": "An internal server error occurred during MIDI processing.", "detail": str(e)}
56
+ )
midi_utils.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import mido
2
+ from io import BytesIO
3
+
4
+ def process_midi(midi_bytes: bytes) -> BytesIO:
5
+ """处理MIDI文件:将所有音符提高一个半音"""
6
+ with BytesIO(midi_bytes) as input_buffer:
7
+ mid = mido.MidiFile(file=input_buffer)
8
+
9
+ for track in mid.tracks:
10
+ for msg in track:
11
+ if msg.type in ['note_on', 'note_off']:
12
+ if msg.note < 127:
13
+ msg.note += 1
14
+
15
+ output_buffer = BytesIO()
16
+ mid.save(file=output_buffer)
17
+ output_buffer.seek(0)
18
+
19
+ return output_buffer
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ mido==1.2.10
4
+ python-multipart