---------------------------------------- | |
python virtualenv invoking without activate | |
April 26th, 2021 | |
---------------------------------------- | |
I like python. I do not like python packaging. I run into the same | |
problem again and again: I want to make a useful tool like | |
'burrow' that can be distributed and used by others (or myself on | |
other systems). Inevitably I'll need to use other packages, | |
though, so I'll need to pip-install those. I don't want to pollute | |
the system, though, so I'd better create a virtual environment and | |
install those there. So now I have my requirements.txt file and | |
can do things inside this little container, but now what? | |
Do I bundle this thing and put it in pip? Am I now expecting | |
someone else will pip install it globally to run it on their | |
system? Of course not, because everything python should be safely | |
stored away in a virtual environment. But I don't want them to | |
write a program that uses my program as a library. I just want to | |
invoke it? Does that change the rules? Will my app's dependencies | |
then pollute their system? | |
And then I throw my hands in the air and give up and do something | |
else. | |
Well, recently I decided I wanted to work on a side-project on | |
cosmic that khuxkm started in python: an anonymous remailer that | |
actually works over email. We'd gone down this path in the past | |
and it almost worked. I had motivation and wanted to see it | |
through. Immediately I knew I was about to hit that problem from | |
above, though. In fact, I was going to hit it with even more | |
complications. | |
See, in order to handle incoming mail and pass it off to a script | |
I was using a feature of ~/.forward that lets you do that. The | |
.forward file works just like the aliases system file, but only on | |
the right-hand side of an alias definition. That means you can do | |
more than just specify an email or emails to deliver the mail to, | |
you can pipe it to a script like so: | |
|/home/anonhmmst/mailhandler/parse_email.py | |
That leading pipe is important. It's also important to know that | |
scripts invoked this way are passed the contents of the incoming | |
mail, but invoked by the 'nobody' user. That's a security thing | |
and for the best, but it complicated my script running. | |
If I used the anonhmmst user and installed python packages for | |
this parse_email.py script at the user-level they wouldn't work | |
when invoked by nobody. I needed to set up a virtual environment | |
to get everything bundled, but I also needed a way to invoke it | |
without having to manually activate the virtual environment first. | |
The solution turned out to be pretty simple: | |
- make the python script executable | |
- point the hashbang at the virtual environment python binary | |
In my case: | |
#!/home/anonhmmst/mailhandler/env/bin/python3 | |
I had to do a bit more work on cosmic with the sudoers file to | |
enable the nobody user to run some cosmic-specific scripts, but | |
the virtual-environment setup was the big take-away. It doesn't | |
solve all my python packaging woes, but it fixed this one nicely. | |
What about you? What do you do in these situations? Do you pip | |
install binaries as your user without virtual environments for | |
utilities or do you wrap them in a virtual environment somehow? | |
How do you distribute your own projects? |