Quarto does not allow multiple virtual environments to be used in a single quarto render
call.
To work around this, I wrote a script that renders each index.qmd in my posts directory. It sets the QUARTO_PYTHON variable for each render.
I use pyenv. The paths to the python executable is in the hidden .pyenv directory. Pyenv caches the package downloads, which saves a lot of space. Naming the environment the same as the post allows me to use the shared name as the dictonary key.
Finally, render the whole project. I use freeze: true
in the posts/_metadata.yml, so this last render does not affect what was just accomplished.
(also, my initials are mvp. I swear I am not that conceded)
import os
import subprocess
= {
envs 'base':"/Users/mvp/.pyenv/versions/quarto_base/bin/python",
'NGBoost':"/Users/mvp/.pyenv/versions/NGBoost/bin/python",
'llm':"/Users/mvp/.pyenv/versions/llm/bin/python",
}
dir = os.path.join(os.getcwd(),'posts')
= [i for i in os.listdir(dir) if '.' not in i]
paths
for path in paths:
if path in envs.keys():
= envs[path]
python_v else:
= envs['base']
python_v print(f'rendering...')
= f'QUARTO_PYTHON={python_v} quarto render posts/{path}/index.qmd'
process print(f'cmd: {process}')
= subprocess.run(process, shell=True)
result
"quarto render", shell=True) subprocess.run(
I tried to use the pre-render argument in _quarto.yml, but I would get this weird error where the render would stall.
project:
type: website
pre-render: multienv.py
website:
title: Posts
navbar:
...
In theory this should work with just one quarto render
(if I removed the last subprocess.run). I couldn’t get it to run, so I just use python multienv.py