[{"data":1,"prerenderedAt":234},["ShallowReactive",2],{"article-0030_dummy_article":3,"surround-\u002Farticle\u002F0030_dummy_article":225},{"id":4,"title":5,"body":6,"date":204,"description":205,"extension":206,"images":207,"meta":212,"navigation":44,"path":213,"seo":214,"stem":215,"tags":216,"thumbnail":27,"tools":220,"__hash__":224},"articles\u002Farticle\u002F0030_dummy_article.md","Automating Your Pipeline with Python",{"type":7,"value":8,"toc":199},"minimark",[9,13,18,21,116,135,138,142,149,178,182,189,192,195],[10,11,12],"p",{},"The work that isn't animation — renaming frames, building folder trees, converting formats — quietly eats hours. Python makes it disappear.",[14,15,17],"h2",{"id":16},"project-setup","Project setup",[10,19,20],{},"Write this once, run it at the start of every job:",[22,23,28],"pre",{"className":24,"code":25,"language":26,"meta":27,"style":27},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import os, sys\n\nname = sys.argv[1]\nbase = f\"\u002FUsers\u002Fyou\u002FProjects\u002F{name}\"\n\nfor folder in [\n    \"01_assets\u002Ffootage\", \"01_assets\u002Faudio\",\n    \"02_project_files\",\n    \"03_renders\u002Fwip\", \"03_renders\u002Ffinal\",\n    \"04_delivery\"\n]:\n    os.makedirs(f\"{base}\u002F{folder}\", exist_ok=True)\n\nprint(f\"Created: {name}\")\n","python","",[29,30,31,39,46,52,58,63,69,75,81,87,93,99,105,110],"code",{"__ignoreMap":27},[32,33,36],"span",{"class":34,"line":35},"line",1,[32,37,38],{},"import os, sys\n",[32,40,42],{"class":34,"line":41},2,[32,43,45],{"emptyLinePlaceholder":44},true,"\n",[32,47,49],{"class":34,"line":48},3,[32,50,51],{},"name = sys.argv[1]\n",[32,53,55],{"class":34,"line":54},4,[32,56,57],{},"base = f\"\u002FUsers\u002Fyou\u002FProjects\u002F{name}\"\n",[32,59,61],{"class":34,"line":60},5,[32,62,45],{"emptyLinePlaceholder":44},[32,64,66],{"class":34,"line":65},6,[32,67,68],{},"for folder in [\n",[32,70,72],{"class":34,"line":71},7,[32,73,74],{},"    \"01_assets\u002Ffootage\", \"01_assets\u002Faudio\",\n",[32,76,78],{"class":34,"line":77},8,[32,79,80],{},"    \"02_project_files\",\n",[32,82,84],{"class":34,"line":83},9,[32,85,86],{},"    \"03_renders\u002Fwip\", \"03_renders\u002Ffinal\",\n",[32,88,90],{"class":34,"line":89},10,[32,91,92],{},"    \"04_delivery\"\n",[32,94,96],{"class":34,"line":95},11,[32,97,98],{},"]:\n",[32,100,102],{"class":34,"line":101},12,[32,103,104],{},"    os.makedirs(f\"{base}\u002F{folder}\", exist_ok=True)\n",[32,106,108],{"class":34,"line":107},13,[32,109,45],{"emptyLinePlaceholder":44},[32,111,113],{"class":34,"line":112},14,[32,114,115],{},"print(f\"Created: {name}\")\n",[22,117,121],{"className":118,"code":119,"language":120,"meta":27,"style":27},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","python setup.py client-name\n","bash",[29,122,123],{"__ignoreMap":27},[32,124,125,128,132],{"class":34,"line":35},[32,126,26],{"class":127},"sBMFI",[32,129,131],{"class":130},"sfazB"," setup.py",[32,133,134],{"class":130}," client-name\n",[10,136,137],{},"Whole folder tree, named consistently, in under a second.",[14,139,141],{"id":140},"batch-rename-frames","Batch rename frames",[10,143,144,145,148],{},"AE renders frames like ",[29,146,147],{},"comp_[0000].png",". This cleans them up:",[22,150,152],{"className":24,"code":151,"language":26,"meta":27,"style":27},"from pathlib import Path\n\nrender_dir = Path(\"\u002Fpath\u002Fto\u002Frenders\")\nfor i, f in enumerate(sorted(render_dir.glob(\"*.png\"))):\n    f.rename(render_dir \u002F f\"output_{i:04d}.png\")\n",[29,153,154,159,163,168,173],{"__ignoreMap":27},[32,155,156],{"class":34,"line":35},[32,157,158],{},"from pathlib import Path\n",[32,160,161],{"class":34,"line":41},[32,162,45],{"emptyLinePlaceholder":44},[32,164,165],{"class":34,"line":48},[32,166,167],{},"render_dir = Path(\"\u002Fpath\u002Fto\u002Frenders\")\n",[32,169,170],{"class":34,"line":54},[32,171,172],{},"for i, f in enumerate(sorted(render_dir.glob(\"*.png\"))):\n",[32,174,175],{"class":34,"line":60},[32,176,177],{},"    f.rename(render_dir \u002F f\"output_{i:04d}.png\")\n",[14,179,181],{"id":180},"notify-on-render-complete","Notify on render complete",[10,183,184,185,188],{},"Install ",[29,186,187],{},"watchdog"," and point it at your renders folder. It fires a desktop notification (or a Slack message) the moment new files appear. No more tabbing back to check.",[190,191],"hr",{},[10,193,194],{},"Start with the folder script. Customize it to your actual workflow. Then find the next annoying repetitive thing and automate that. That's it.",[196,197,198],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":27,"searchDepth":41,"depth":41,"links":200},[201,202,203],{"id":16,"depth":41,"text":17},{"id":140,"depth":41,"text":141},{"id":180,"depth":41,"text":181},"14 November, 2025","The repetitive parts of production work — file management, render tracking, asset organization — are exactly what Python is built to eliminate. Here's where to start.","md",[208,210],{"src":27,"alt":209},"A terminal showing a Python script output listing renamed render files",{"src":27,"alt":211},"A folder structure generated automatically by a project setup script",{},"\u002Farticle\u002F0030_dummy_article",{"title":5,"description":205},"article\u002F0030_dummy_article",[217,26,218,219],"automation","pipeline","workflow",[221,222,223],"Python","After Effects","Terminal","Dx23q0uvfYWR0uPPRHIDBU1RjA4HkKgCDrVwnzmwrHA",[226,230],{"title":227,"path":228,"stem":229,"children":-1},"After Effects Expressions for Noobs","\u002Farticle\u002F0020_dummy_article","article\u002F0020_dummy_article",{"title":231,"path":232,"stem":233,"children":-1},"Generative Art and Animation","\u002Farticle\u002F0040_dummy_article","article\u002F0040_dummy_article",1776374632750]