| ---------------------------------------- | |
| 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? |