All MicroEvals
I'm getting a bunch of 404 errors during the apt dependency ...
Create MicroEval

I'm getting a bunch of 404 errors during the apt dependency ...

Prompt

I'm getting a bunch of 404 errors during the apt dependency install process for the following Modal script (for example: E: Failed to fetch http://deb.debian.org/debian-security/pool/updates/main/x/xorg-server/xvfb_1.20.11-1%2bdeb11u18_amd64.deb 404 Not Found [IP: 151.101.66.132 80]). I can't run it without the dependencies. Please fix the following code: import os import shutil import subprocess import tempfile from pathlib import Path import modal from fastapi import BackgroundTasks, FastAPI, File, HTTPException, UploadFile, status from fastapi.responses import FileResponse # ----------------------------------------------------------------------------- # 1. Define the Custom Modal Container Image # ----------------------------------------------------------------------------- image = ( modal.Image.debian_slim(python_version="3.11") .apt_install( "ffmpeg", # Video/audio encoding (with NVENC support) "openjdk-17-jre", # Java runtime required by midis2jam2 "xvfb", # Virtual display for headless OpenGL rendering "libgl1-mesa-dri", # OpenGL Mesa drivers "libgl1", # Core OpenGL library "libglu1-mesa", # OpenGL utility library "fluidsynth", # MIDI audio synthesizer "fluid-soundfont-gm", # Default General MIDI SoundFont (.sf2) "pulseaudio", # Virtual audio routing for headless capture "wget", # For fetching the midis2jam2 executable/jar ) .pip_install( "fastapi[standard]>=0.115.0", "python-multipart>=0.0.9", "uvicorn>=0.30.0", ) # Download and configure midis2jam2 and a CLI wrapper script .run_commands( "mkdir -p /opt/midis2jam2", "wget -q -O /opt/midis2jam2/midis2jam2.jar " "https://github.com/wyskoj/midis2jam2/releases/download/v1.7.0/midis2jam2-1.7.0-linux-x64.jar || true", # Create an executable wrapper on PATH if invoking `midis2jam2` directly "printf '#!/bin/bash\nexec java -jar /opt/midis2jam2/midis2jam2.jar \"$@\"\n' > /usr/local/bin/midis2jam2", "chmod +x /usr/local/bin/midis2jam2", ) ) app = modal.App(name="midis2jam2-gpu-renderer", image=image) # Initialize the FastAPI application web_app = FastAPI( title="MIDI Visualizer GPU Rendering Service", description="Converts .mid files into 3D visualizer .mp4 videos using midis2jam2 and NVIDIA GPUs.", version="1.0.0", ) # Allowed extensions and MIME types for MIDI validation ALLOWED_EXTENSIONS = {".mid", ".midi"} ALLOWED_CONTENT_TYPES = { "audio/midi", "audio/x-midi", "application/x-midi", "application/octet-stream", # Often sent by curl or generic clients } # ----------------------------------------------------------------------------- # 2. Helper Functions # ----------------------------------------------------------------------------- def cleanup_temp_dir(dir_path: str) -> None: """Deletes the temporary directory and all files inside it.""" try: if os.path.exists(dir_path): shutil.rmtree(dir_path) except Exception as exc: print(f"[WARNING] Failed to delete temporary directory {dir_path}: {exc}") # ----------------------------------------------------------------------------- # 3. FastAPI Endpoints # ----------------------------------------------------------------------------- @web_app.get("/health") async def health_check(): """Simple health check endpoint.""" return {"status": "healthy", "gpu_available": shutil.which("nvidia-smi") is not None} @web_app.post( "/render", response_class=FileResponse, summary="Render a MIDI file to an MP4 video", ) async def render_midi_video( background_tasks: BackgroundTasks, file: UploadFile = File(..., description="The .mid or .midi file to render"), ): # --- Step 1: Validate File Type --- if not file.filename: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Uploaded file must have a valid filename.", ) file_path_obj = Path(file.filename) file_ext = file_path_obj.suffix.lower() if file_ext not in ALLOWED_EXTENSIONS: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid file extension '{file_ext}'. Only .mid and .midi files are accepted.", ) if file.content_type and file.content_type not in ALLOWED_CONTENT_TYPES: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid content type '{file.content_type}'. Expected a MIDI file.", ) # --- Step 2: Create Temporary Working Directory --- temp_dir = tempfile.mkdtemp(prefix="midis2jam2_") input_midi_path = os.path.join(temp_dir, f"input{file_ext}") output_mp4_path = os.path.join(temp_dir, "output.mp4") try: # Save the uploaded MIDI file to the temporary directory content = await file.read() if not content: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Uploaded MIDI file is empty.", ) with open(input_midi_path, "wb") as f: f.write(content) # --- Step 3: Run the GPU-Accelerated Subprocess --- # Configure environment variables to offload OpenGL rendering to the NVIDIA GPU env = os.environ.copy() env["__NV_PRIME_RENDER_OFFLOAD"] = "1" env["__GLX_VENDOR_LIBRARY_NAME"] = "nvidia" # Construct the headless GPU rendering command. # Adjust CLI flags if using a custom headless fork of midis2jam2. render_cmd = [ "xvfb-run", "--auto-servernum", "--server-args=-screen 0 1920x1080x24", "midis2jam2", "--input", input_midi_path, "--output", output_mp4_path, "--soundfont", "/usr/share/sounds/sf2/FluidR3_GM.sf2", "--resolution", "1920x1080", "--fps", "60", "--gpu-accel", # Enable hardware OpenGL rendering "--video-codec", "h264_nvenc" # Use NVIDIA NVENC hardware encoder in FFmpeg ] process = subprocess.run( render_cmd, env=env, capture_output=True, text=True, timeout=540, # 9-minute subprocess timeout check=True, ) # Verify the output file was actually generated and is non-empty if not os.path.exists(output_mp4_path) or os.path.getsize(output_mp4_path) == 0: raise RuntimeError( f"Renderer exited with code 0, but output MP4 was not found or was empty. " f"Stdout: {process.stdout} | Stderr: {process.stderr}" ) # --- Step 4: Schedule Cleanup & Return Video --- # Schedule the temp directory to be deleted *after* the FileResponse finishes streaming background_tasks.add_task(cleanup_temp_dir, temp_dir) output_filename = f"{file_path_obj.stem}.mp4" return FileResponse( path=output_mp4_path, media_type="video/mp4", filename=output_filename, ) except HTTPException: # Clean up immediately if validation failed after temp_dir creation cleanup_temp_dir(temp_dir) raise except subprocess.TimeoutExpired as exc: cleanup_temp_dir(temp_dir) raise HTTPException( status_code=status.HTTP_504_GATEWAY_TIMEOUT, detail="MIDI rendering timed out.", ) from exc except subprocess.CalledProcessError as exc: cleanup_temp_dir(temp_dir) error_msg = exc.stderr.strip() or exc.stdout.strip() or "Unknown subprocess error" raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"midis2jam2 rendering failed (exit code {exc.returncode}): {error_msg}", ) from exc except Exception as exc: cleanup_temp_dir(temp_dir) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"An unexpected error occurred during video rendering: {str(exc)}", ) from exc # ----------------------------------------------------------------------------- # 4. Bind the FastAPI App to a GPU-Accelerated Modal Function # ----------------------------------------------------------------------------- @app.function( gpu="L40S", # Assign an NVIDIA T4 GPU (supports OpenGL + NVENC) timeout=600, # 10-minute maximum execution timeout per request scaledown_window=120, # Keep container warm for 2 minutes after a request ) @modal.asgi_app() def serve(): return web_app

Drag to resize
Drag to resize
Drag to resize