Reputation: 598
I'm sure this question gets asked a lot but I am struggling to find answers myself. There seems to be a lot out there when using virtualenv but almost nothing for venv.
I've created a program running a mixture of Python and Powershell that i want to be able to install on other Windows machines. To do this I need to replicate the venv.
One solution would simply be to create a new venv on each machine and pip install the requirements. However this falls over as soon as someone has a newer version of Python as there's no way to specify the version when creating a venv on a Windows machine.
I've tried simply copying the venv within my inno install package and then pip installing into that but that doesn't work. The settings for the venv still match the original machine and so fall over when in a different location. It then installs all the packages to the default python location instead.
I've given venv-pack a go but that doesn't work.
Hopefully there's a solution out there. I've looked at pyinstaller but that appears to rely on the program being completely python, which mine is not.
Thanks!
//////////////////////////// UPDATE ////////////////////////////
I have actually been able to make a copy paste venv work by changing a few lines within the files of the venv. If I can work out how to automate this then venv distribution will be incredibly simple.
The following files contain the venv's location:
If this can be replaced in all three then the venv works fine (or at least it appears to so far)
Upvotes: 2
Views: 1058
Reputation: 598
Ok it looks like I've got this working with a very simple bit of code. This seems to be working on any machine I install it on though it hasn't been tested in situations where there are multiple versions of Python.
Here's what I did:
First I created the python script set_dir.py to output the location of the venv to a json file, you just need to edit the venv name. This could be easily automated I just haven't got round to it yet:
import os
import json
venv_dir = "/YOUR_VENV_NAME"
cwd = os.getcwd()
cwd = cwd.replace("\\","/")
cwd += venv_dir
dir_path = {
"path": cwd
}
with open('path.json', 'w', encoding='utf-8') as f:
json.dump(dir_path, f, ensure_ascii=False, indent=4)
Next in the venv\scripts folder I added this line to the top of Activate.ps1:
$Data = Get-Content -Raw "path.json" | ConvertFrom-Json
and changed the $env:VIRTUAL_ENV variable to this:
$env:VIRTUAL_ENV=$Data.path
Then in the activate.bat I edited the VIRTUAL_ENV variable to the following:
set VIRTUAL_ENV=%cd%
Now I can distribute my project using inno like so:
Get the project requirements using pip:
py -m pip freeze > requirements.txt
Delete the venv and create a new one with the exact same name, then copy in the edited activate files.
Add all the required files to the inno installer and run a script at the end to get your venv path and install all your required packages. I wrote the following PowerShell script and then converted it to an exe with Win-PS2EXE:
Set-ExecutionPolicy Unrestricted -Scope Process -Force
py .\set_dir.py
MY_VENV\scripts\activate
py -m pip install --upgrade pip
py -m pip install -r requirements.txt
exit
I will at some point write something that can do all this automatically but for now I hope this helps someone!
There's probably a lot wrong with doing things this way but at the moment it's doing the job. Down the line it may cause some catastrophic errors but they're for my future self to deal with. Sucks to be him!
Upvotes: 3