I needed a module for a shell script I've written in Python, so I used pipenv to install it. I can run the command fine using:
~$ pipenv run python3 foo
Now, if I want to just run ~$ foo on the command line (fish shell on MacOS, homebrew installed), how do I invoke the pipenv environment in the shebang of my Python script? Or is there a better way?
As documented here https://pipenv.readthedocs.io/en/latest/ you need to activate the virtual environment first. This will spawn another shell with the virtual environment activated
$ pipenv shell
so that you can run
$ python foo
to execute your script. Then you can use
#!/usr/bin/env python
on the first line of your script and make the script executable (chmod +x foo.py) so that you can run
$ ./foo
If the location of that script is part of your PATH environment variable, you should be able to run now
$ foo.py
If you don't like the extension you will have to remove from your script too
With pipenv-shebang you can run your script with
pipenv-shebang PATH/SCRIPT
or you could insert the shebang
#!/usr/bin/env pipenv-shebang
to run it with just PATH/SCRIPT.
create wrapper file like below works for me, but little bit hacky way.
import subprocess
if __name__ == '__main__':
subprocess.run(['pipenv', 'run', 'foo'])
Related
I have a python file which uses the prettytable. I also have a bash script that opens and runs it using xQuartz. When I open xQuartz and run the file from there, it works as expected, however when I try to run it using the script, it is unable to find my prettytable module. What might be going on?
bash script line:
xterm -geometry 55x24+000+000 -hold -e /bin/bash -l -c "python3 server.py 1"
running python3 server.py 1 on xQuartz terminal is fine. It also works if I run xterm from the mac terminal and do the same.
As pointed out by #DiegoTorresMilano, you may be running a different version of python 3 depending on what's in your ~/.bash_profile or ~/.bashrc. This is possible if you have more than one version of python 3 installed.
When you are running an interactive non-login bash session, your ~/.bash_profile will be sourced first, and then your ~/.bashrc. Since your ~/.bashrc will be sourced second, it can override things set in your ~/.bash_profile.
When you run bash with the -l option, this tells bash to run as though it was a login shell. Then the "Invocation" section of the bash man page tells us that ~/.bash_profile will be sourced by a login shell, but not ~/.bashrc.
What you should try is running python3 --version in an interactive xQuartz terminal. This will give you output something like Python x.y.z (for example, Python 3.8.5). Then you can run that specific python version by using pythonx.y in your bash script (for example, if the output of your python3 --version was Python 3.8.5, you should use python3.8 in your bash script).
I am working on the project where I need to run my script daily at a specific time. I am using crontab/cronjob to run shell script. Using shell script I want to activate virtualenv and python interpreter to run some commands and deactivate it. I have tried
#!/bin/bash
bash
source virtual_env/bin/activate
cd src
python script.py
but didn't work for me
Note: I can activate my virtualenv and use /home/bin/virtual_env/python the interpreter manually but i wanted to it via shell script.
Often there is no need to activate a virtual environment:
#!/usr/bin/env sh
PYTHON_BIN='/path/to/virtual_environment/bin/python'
pushd 'src'
"${PYTHON_BIN}" 'script.py'
I am trying to run a python script under python 2 virtualenv. How to run it via batch script/ python script?
I have installed both python2 and python 3 and created virtual env too. I tried it invoking via python script but it didn't even enter the virtualenv. Then i tried the below batch script. But It just executed the first line of the code. i.e just activating the virtual environment. but other lines are not getting executed.
I even tried to execute the 1st line of batch script separately in a bat file and then invoke others using perl/python. but none of them worked.
Please do provide a way to execute these commands either using python script or
a batch file, which I will need to run it via perl/python
The batch file i used :
C:\venv-2\Scripts\activate
pushd <some path>
python test.py
deactivate
Just directly use the virtualenv's Python interpreter:
pushd some_path
c:\venv-2\scripts\python test.py
popd
Not having a Windows environment to hand, this is a non-answer for *nix which might be adapted to Windows.
Instead of calling the venv bin directly, try activating it within a script. For example:
# my-script.sh
# activate
source venv/bin/activate
# this should be in the venv
which python3
python3 -c 'print("Hello from python3")'
Then $ bash my-script.sh should print out which python3 it thinks is in use within the script.
See also A Python script that activates the virtualenv and then runs another Python script? for the same idea done better...
I got the the batch file executed by giving,
C:\venv-2\Scripts\activate & pushd <some path> & python test.py & deactivate
inside the batch file. And used perl script to call the batch file
system('start test.bat')
I tried to make a cron job on crontab which runs a python script on AWS ec2. My python script includes a module that is only available for python3.
Using the following command I changed the ec2 default python interpreter from python2.7 to python3.4
Source /home/ec-2user/venv/python34/bin/activate
and then using pip install, I installed the required module for python3.4. So now the default interpreter is python3.4 and when I run the script on ec2-user directory using the following command:
python test.py
the program runs without any problem (so I am sure the module is installed correctly).
But when I assign python file to a cronjob
* * * * * python test.py
It does not work. Checking the mail, the error is:
“No module found named “xxxxx” “
But as I said it worked fine outside of the cron.
I was wondering if you can help me with this problem. I appreciate your time and information.
You have to make a shell script which will do the steps of changing to script directory, activating virtual environment and then running it.
Example:
#!/bin/bash
cd $YOUR_DIR
. venv/bin/activate
python3.4 test.py
Then you call this script in cron with
/bin/bash /.../script.sh
What you could do additionally is
chmod +x test.py
and add/update first line to:
#!/usr/bin/env python3.4
This way you can just run Python script with ./test.py
Create file as 'user_cron.sh'
#!/bin/bash
cd '/root/my_new_project_python'
. my_project_venv/bin/activate
python3 main.py
set the cron using crontab -e
I recently came across this in a cron script at my place of work:
/bin/bash -c "[[ -s $HOME/.pythonbrew/etc/bashrc ]] && source $HOME/.pythonbrew/etc/bashrc && pythonbrew use 2.6.7 && pythonbrew venv use someapp && python /opt/someapp/bin/someapp.py"
This is for a system-wide (multi-user) installation of Pythonbrew.
It works. But please tell me there's a better way.
Addendum
To clarify what I'm looking for: I'd like a one-line command to run my script though a virtualenv tied to pythonbrew. With virtualenv alone, I could do something like this:
/opt/someapp/venv/bin/python /opt/someapp/bin/someapp.py
What I don't want is another script to run my script (like that cron command above).
I believe it can be done by using the python binary directly from you pythonbrew virtual environment.
By default its in ~/.pythonbrew/venvs/Python-<version>/<name of venv>/bin/python
But I think you can change the path with an environmental variable.
So just change the first half of the line you added to reference the pythonbrew virtual environment python binary and it should work.
On the first line on your python script add a shebang (#!) followed by a path to your target python. Then make the python script executable. It can then be executed directly from the command line (crontab, another bash script, whatever).
make a virtual env in your temp dir:
$ cd /tmp
$ virtualenv venv
the path to your python in that venv is /tmp/venv/bin/python
Using an editor create a simple script containing all of the following:
#!/tmp/venv/bin/python
print("hello world")
Save it in your home directory as "mypyscript.py"
make it executable:
$ chmod 755 mypyscript.py
Now you should be able to execute it using the filename directly on the command line:
$ ./mypyscript.py
hello world
Do this to your someapp.py substituting the relevant path to your python and that should work.
The trick turned out to be locating the pythonbrew virtualenv's python binary. Mark's answer pointed me in the right direction. But here's a complete rundown for future reference:
With pythonbrew installed, I did the following (as root on the server):
pythonbrew install 2.6.6
pythonbrew switch 2.6.6
pythonbrew venv create --no-site-packages myapp
I had a pip freeze file, so I set up my virtualenv using that:
/usr/local/pythonbrew/venvs/Python-2.6.6/myapp/bin/pip install -r /tmp/requirements.pip
Now my python binary can be found at /usr/local/pythonbrew/venvs/Python-2.6.6/myapp/bin/python. So to run my script:
/usr/local/pythonbrew/venvs/Python-2.6.6/myapp/bin/python /opt/myapp/bin/myapp.py