$ cat node-template.py
Drive Audio Reader
// Reads an audio file from Drive and outputs it as an Audio file.
Input
Storage
template.py
1import os2import sys3import json4import traceback5import requests67EMBLEMA_API_BASE_URL = os.getenv("EMBLEMA_API_BASE_URL")8USER_TOKEN = os.getenv("USER_TOKEN")9OUTPUT_DIR = "/data/output"1011if not EMBLEMA_API_BASE_URL:12 raise ValueError("EMBLEMA_API_BASE_URL environment variable not set")131415def api_request_json(method, path, **kwargs):16 """Make authenticated API request and return JSON response."""17 if not USER_TOKEN:18 raise ValueError("USER_TOKEN environment variable not set")1920 headers = {21 "Authorization": f"Bearer {USER_TOKEN}",22 }23 url = f"{EMBLEMA_API_BASE_URL}{path}"24 response = requests.request(method, url, headers=headers, **kwargs)25 response.raise_for_status()26 return response.json()272829def fetch_audio(drive_item_id_input) -> str:30 """Fetch an audio file from Drive and save it to the output directory.3132 Args:33 drive_item_id_input: Single Drive Item ID (string). Arrays are rejected.3435 Returns:36 The output filename saved to /data/output/37 """38 # Normalize input — reject arrays, this is a single-audio reader39 if isinstance(drive_item_id_input, list):40 if len(drive_item_id_input) == 1:41 drive_item_id = drive_item_id_input[0]42 else:43 raise ValueError(44 f"Drive Audio Reader accepts a single audio file, got {len(drive_item_id_input)} items. "45 "Use one Drive Audio Reader per audio file."46 )47 elif isinstance(drive_item_id_input, str):48 drive_item_id = drive_item_id_input49 else:50 raise ValueError(f"driveItemId must be a string, got {type(drive_item_id_input).__name__}")5152 if not drive_item_id:53 raise ValueError("No valid Drive Item ID provided")5455 # Get presigned download URL + metadata56 download_info = api_request_json("GET", f"/api/v2/drive/items/{drive_item_id}/download")5758 presigned_url = download_info.get("url")59 file_name = download_info.get("name", "audio.mp3")60 mime_type = download_info.get("mimeType", "")6162 if not presigned_url:63 raise ValueError("Download API did not return a presigned URL")6465 # Validate that the file is an audio file66 if mime_type and not mime_type.startswith("audio/"):67 raise ValueError(68 f"Selected Drive item is not an audio file (mimeType: {mime_type}). "69 "Please select an audio file."70 )7172 # Download the audio binary from presigned URL73 audio_response = requests.get(presigned_url, timeout=120)74 audio_response.raise_for_status()7576 # Save to output directory77 os.makedirs(OUTPUT_DIR, exist_ok=True)78 out_path = os.path.join(OUTPUT_DIR, file_name)79 with open(out_path, "wb") as f:80 f.write(audio_response.content)8182 return file_name838485def main():86 """Main execution function"""87 try:88 input_json = sys.stdin.read()89 execution_input = json.loads(input_json)9091 inputs = execution_input.get("inputs", {})92 drive_item_id = inputs.get("driveItemId")9394 if not drive_item_id:95 raise ValueError("Required input 'driveItemId' not provided")9697 filename = fetch_audio(drive_item_id)9899 output = {100 "audio": filename,101 }102103 print(json.dumps(output, indent=2))104105 except requests.HTTPError as e:106 error_output = {107 "error": f"API request failed: {e}",108 "errorType": "HTTPError",109 "status": e.response.status_code,110 "detail": e.response.text,111 }112 print(json.dumps(error_output), file=sys.stderr)113 sys.exit(1)114 except Exception as e:115 error_output = {116 "error": str(e),117 "errorType": type(e).__name__,118 "traceback": traceback.format_exc(),119 }120 print(json.dumps(error_output), file=sys.stderr)121 sys.exit(1)122123124if __name__ == "__main__":125 main()