How to run Python script in venv? - python

Im trying to start telegram bot in Linux using venv. But bot starts only if venv activated manualy.
Python code:
#!env/bin/python3
# -*- coding: utf-8 -*-
import config
import telebot
bot = telebot.TeleBot(config.token)
#bot.message_handler(content_types=["text"])
def repeat_all_messages(message):
bot.send_message(message.chat.id, message.text)
if __name__ == '__main__':
bot.infinity_polling()
Bot starts with comands:
root#ubuntu-s-1vcpu-1gb-ams3-01:~/jira_bot# source env/bin/activate
(env) root#ubuntu-s-1vcpu-1gb-ams3-01:~/jira_bot# python3 sreda_bot.py
But if i try to start it without activating venv:
root#ubuntu-s-1vcpu-1gb-ams3-01:~/jira_bot# python3 sreda_bot.py
Traceback (most recent call last):
File "sreda_bot.py", line 4, in <module>
import telebot
ModuleNotFoundError: No module named 'telebot'

Finally I inserted full path to the interpreter in the venv in shebang line:
#!/root/jira_bot/env/bin/python3
Used ./sreda_bot.py instead of python3 sreda_bot.py. And it works fine.

Considering Python Shebang Syntax is like the following
#!interpreter [optional-arg]
You just need to locate your Virtual ENV's interpreter location.
#!<venv path>/bin/python[3.x]
Thus assuming your Virtual ENV is located at ~/jira_bot base from the following.
root#ubuntu-s-1vcpu-1gb-ams3-01:~/jira_bot# source env/bin/activate
(env) root#ubuntu-s-1vcpu-1gb-ams3-01:~/jira_bot# python3 sreda_bot.py
So your shebang should be #!/root/jira_bot/bin/python3

The purpose of virtual environments in Python is to create a physical separation between projects and their modules. In this case, the telebot module that you installed in the virtual environment, isn't in scope (available for use) outside of the virtual environment.

Related

Unable to access packages inside virtual environment on startup

I am working on creating a bash file on my raspberry pi in order to be able to launch a webapp project that I have made when the raspberry pi starts up. I have been able to figure out most of it, except for I have issues with the virtual environment letting me access my packages that were installed in the virtual environment. When I run
workon tm
python main.py
in the terminal I am able to get my project working fine. But when I run my bash file
#!/bin/bash
# startup.sh
#Open Chromium on the Raspberry Pi on fullscreen on bootup. Then open the virtual environemnt, and then run our python script
#su - pi -c "/usr/bin/chromium-browser --start-fullscreen 127.0.0.1:5000"
cd /
cd /home/pi/MySQLAppTrueTrue
source /usr/local/bin/virtualenvwrapper.sh
source ~/.bashrc
#workon /home/pi/.virtualenvs/tm
workon tm
sudo python /home/pi/MySQLAppTrueTrue/main.py
I get the error
pi#raspberrypi:~/MySQLAppTrueTrue $ ./startup.sh
Traceback (most recent call last):
File "/home/pi/MySQLAppTrueTrue/main.py", line 1, in <module>
from webapp import app #import the web app
File "/home/pi/MySQLAppTrueTrue/webapp/__init__.py", line 2, in <module>
from flask_mysqldb import MySQL #import mySQL
ImportError: No module named flask_mysqldb
Does this mean that my workon tm line isnt actually causing the device to be working on the virtual environment. If so how do I get that to work? Or do I just need to install my packages globally instead of in the virtual environment?
Instead of all that virtualenvwrapper workon magic, you should probably just use that virtualenv's Python interpreter:
#!/bin/bash
cd /home/pi/MySQLAppTrueTrue
sudo /home/pi/.virtualenvs/tm/bin/python /home/pi/MySQLAppTrueTrue/main.py

Mac gcloud install ImportError: No module named __future__

When installing gcloud for mac I get this error when I run the install.sh command according to docs here:
Traceback (most recent call last):
File "/path_to_unzipped_file/google-cloud-sdk/bin/bootstrapping/install.py", line 8, in <module>
from __future__ import absolute_import
I poked through and echoed out some stuff in the install shell script. It is setting the environment variables correctly (pointing to my default python installation, pointing to the correct location of the gcloud SDK).
If I just enter the python interpreter (using the same default python that the install script points to when running install.py) I can import the module just fine:
>>> from __future__ import absolute_import
>>>
Only other information worth noting is my default python setup is a virtual environment that I create from python 2.7.15 installed through brew. The virtual environment python bin is first in my PATH so python and python2 and python2.7 all invoke the correct binary. I've had no other issues installing packages on this setup so far.
If I echo the final line of the install.sh script that calls the install.py script it shows /path_to_virtualenv/bin/python -S /path_to_unzipped_file/google-cloud-sdk/bin/bootstrapping/install.py which is the correct python. Or am I missing something?
The script uses the -S command-line switch, which disables loading the site module on start-up.
However, it is a custom dedicated site module installed in a virtualenv that makes a virtualenv work. As such, the -S switch and virtualenvs are incompatible, with -S set fundamental imports such as from __future__ break down entirely.
You can either remove the -S switch from the install.bat command or use a wrapper script to strip it from the command line as you call your real virtualenv Python.
I had the error below when trying to run gcloud commands.
File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/lib/gcloud.py", line 20, in <module>
from __future__ import absolute_import
ImportError: No module named __future__
If you have your virtualenv sourced automatically you can specify the environment variable CLOUDSDK_PYTHON i.e. set -x CLOUDSDK_PYTHON /usr/bin/python to not use the virtualenv python.
In google-cloud-sdk/install.sh go to last line, remove variable $CLOUDSDK_PYTHON_ARGS as below.
"$CLOUDSDK_PYTHON" $CLOUDSDK_PYTHON_ARGS "${CLOUDSDK_ROOT_DIR}/bin/bootstrapping/install.py" "$#"
"$CLOUDSDK_PYTHON" "${CLOUDSDK_ROOT_DIR}/bin/bootstrapping/install.py" "$#"

whitespace in path in bash command python file

I set up a python virtual environment in python 3.6. the venv works, but pip does not. When running a pip command I get this error:
-bash: /Users/username/Library/Application Support/McNeel/Rhinoceros/Scripts/craftr_rhino/venv/bin/pip: "/Users/username/Library/Application\: bad interpreter: No such file or directory
There seems to be a problem with the white space in the bash command in the (by virtualenv generated) pip file:
#!"/Users/username/Library/Application Support/McNeel/Rhinoceros/Scripts/craftr_rhino/venv/bin/python3"
# -*- coding: utf-8 -*-
import re
import sys
from pip import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())
The path is already in between quotations, how can I get pip to understand the bash command?
edit:
Already tried:
".../Application\ Support/..."
".../Application\\ Support/..."
'.../Application Support/...'
No quotation needed for bash and backslash all white spaces like this:
#!/Users/username/Library/Application\ Support/McNeel/Rhinoceros/Scripts/craftr_rhino/venv/bin/python3
I'm not on a Mac now, but I believe there is somewhere on OSX a command call env, on linux is under /usr/bin path, that can brings up your python environment:
#!/usr/bin/env python
And you just have to set the python3.6 in our $python shell var when call your script or set it to your bash.rc file

How to import packages in virtualenv in python shell

I'm trying to make a function to make periodical notifications to users , especially , ios mobile devices.
Specifically, I use 'Scheduled task' of pythonanywhere. (https://help.pythonanywhere.com/pages/ScheduledTasks)
This is my script to send notifications.
#!/usr/local/bin/python3.4
import sys,os,django
sys.path.append("/home/lkm/Folder/project/")
sys.path.append("/home/lkm/Folder/project/app/myvenv/")
print(sys.path)
os.environ["DJANGO_SETTINGS_MODULE"] = "project.settings"
from push_notifications.models import APNSDevice, GCMDevice
device = APNSDevice.objects.all()
if device is None:
print('No Device')
message = 'Home Fried Potatoes, Yo-nola Bar, Soup du Jour, More...'
device.send_message(message)
But at the line of 'from push_notifications.models import APNSDevice, GCMDevice'
I'm getting an error :
'ImportError: No module named 'push_notifications'
I think it's because of not importing virtualenv because push_notifications package is inside of packages of virtualenv, in mycase 'myvenv' directory.
But even though I import 'myvenv' by 'ImportError: No module named 'push_notifications'.
It makes the same error, do you have the solution for this?
UPDATE (First script , second error message)
#!/home/lkm/folder/project/app/myvenv/bin/python
import sys,os,django
sys.path.append("/home/lkm/folder/project/application/myvenv/bin/../lib/python/site-packages")
print(sys.path)
os.environ["DJANGO_SETTINGS_MODULE"] = "project.settings"
from push_notifications.models import APNSDevice, GCMDevice
device = APNSDevice.objects.all()
if device is None:
print('No Device')
message = 'Home Fried Potatoes, Yo-nola Bar, Soup du Jour, More...'
device.send_message(message)
['/home/lkm/folder/project/application', '/usr/lib/python3.4',
'/usr/lib/python3.4/plat-x86_64-linux-gnu',
'/usr/lib/python3.4/lib-dynload',
'/usr/local/lib/python3.4/dist-packages',
'/usr/lib/python3/dist-packages',
'/home/lkm/folder/project/application/myvenv/bin/../lib/python/site-packages']
Traceback (most recent call last): File
"/home/lkm/folder/project/application/schedule.py", line 9, in
from push_notifications.models import APNSDevice, GCMDevice ImportError: No module named 'push_notifications'
I would change the shebang to use the Python from your virtual environment.
#!/home/lkm/Folder/project/app/myvenv/bin/python
Then you shouldn't have to append the virtual env to the python path, and you can remove the following line.
sys.path.append("/home/lkm/Folder/project/app/myvenv/")
However, if you really want to manually add the virtual env directory to the Python path, then I think you want to include the site-packages directory instead:
sys.path.append("/home/lkm/Folder/project/app/myvenv/python3.4/site-packages")
How are you executing the file?
I see you have:
#!/usr/local/bin/python3.4
which means that if you're executing the file with:
./file.py
it will be executed with the system interpreter.
You need to activate the environment:
$ source env/bin/activate
and execute the file with:
$ python file.py
FWIW, I think the cleanest solution though is to have a setup.py script for your project (packages= argument being the most important) and define an entry point, similar to:
entry_points = {
'console_scripts': ['my-script=my_package.my_module:main'],
}
Then you run python setup.py develop after activating the environment
and you would run the script simply as a command:
$ my-script

Basic Flask Issue w/ Importing

I'm following a Flask tutorial and am getting an import error. I have a file called run.py which contains:
from app import app
app.run(debug = True)
When I run ./run.py, I get:
Traceback (most recent call last):
File "./run.py", line 2, in <module>
from app import app
File "/Users/myName/Desktop/SquashScraper/app/__init__.py", line 1, in <module>
from flask import Flask
ImportError: cannot import name Flask
This seems similar to this issue: http://stackoverflow.com/questions/26960235/python3-cannot-import-name-flask
So I attempted the checked solution by running:
virtualenv -p /usr/bin/python3 my_py3_env
Unfortunately, I get:
The executable /usr/bin/python3 (from --python=/usr/bin/python3) does not exist
Any ideas what may be happening here?
Thanks for the help,
bclayman
If you want your virtual environment to be Python 3 but don't know the installation directory, use which python3. Use that directory in your virtualenv -p [directory] my_py3_env command to set up the Python 3 virtual environment.
I sounds like your pip is installing to your Python 2.X directory. If you're okay with that, you'll need to run the app either with python2 run.py, python2.X run.py where x is your installed version, or change the symlink of python in /usr/bin/python to your installation of Python 2.
This question has some more information.
Regardless of the version of Python that you wish to use, you will need to install Flask to that version of Python. See this question for that.

Categories