Virtual Python enviroment with WINSW - python

I am trying to create a Windows Service which uses a Virtual Python Environment. I create the environment as described here with venv. To create the Windows Service I use winsw.
While I can both run a program in the virtual environment and setup a windows service I cannot figure out how to do both at once.
My first attempt was to call "call win_env/Scripts/activate.bat" in the .bat file which is used by the windows service. This did not work, as he still used the main enviroment and therefore ignored this line of code. Also the second answer in this issue suggests an solution. This also did not work for me as the program still used the main enviroment.
Possible this is because I do not use the env variables in the code but I cannot figure out how I would start the virtual env from there.
When I write that it uses the "main environment" I track this because the program fails because of some missing dependencies (wrong versions). These dependencies are installed in the virtual environment but not in the main environment. If I call the bat files without going into the virtual environment the program fails with the same message.
Error Message:
Exception in thread {X}:
Traceback (most recent call last):
File "{Path}\scoop\apps\anaconda3\current\lib\threading.py", line 973, in _bootstrap_inner
self.run()
File "{Path}\scoop\apps\anaconda3\current\lib\threading.py", line 910, in run
self._target(*self._args, **self._kwargs)
File "{Path}\Sources\{Project}\.\populate_cache.py", line 25, in query_failures_from_db
df = pd.read_sql(statement, con, params=[date_from, date_to])
File "{Path}\Sources\{Project}\win_env\lib\site-packages\pandas\io\sql.py", line 563, in read_sql
pandas_sql = pandasSQL_builder(con)
File "{Path}\Sources\{Project}\win_env\lib\site-packages\pandas\io\sql.py", line 744, in pandasSQL_builder
import sqlite3
File "{Path}\scoop\apps\anaconda3\current\lib\sqlite3\__init__.py", line 23, in <module>
from sqlite3.dbapi2 import *
File "{Path}\scoop\apps\anaconda3\current\lib\sqlite3\dbapi2.py", line 27, in <module>
from _sqlite3 import *
ImportError: DLL load failed while importing _sqlite3: The specified module could not be found.
.bat file:
call uvicorn main:app --port 8590 --host 0.0.0.0
winsw file:
<?xml version="1.0"?>
<!--This configuration file should be placed near the WinSW executable, the name should be the same.E.g. for myapp.exe the configuration file name should be myapp.xmlYou can find more information about configuration options here: https://github.com/kohsuke/winsw/blob/master/doc/xmlConfigFile.md -->
<configuration>
<id>Test Programm</id>
<name>Test Programm</name>
<description> XXX. </description>
<executable>{PathToBatfile}</executable>
<onfailure delay="10 sec" action="restart"/>
<onfailure delay="20 sec" action="restart"/>
<onfailure action="none"/>
<resetfailure>1 hour</resetfailure>
<workingdirectory>{PathToWorkingdirectory}</workingdirectory> // .bat file is located here
<priority>Normal</priority>
<stoptimeout>15 sec</stoptimeout>
<stopparentprocessfirst>true</stopparentprocessfirst>
<startmode>Automatic</startmode>
<waithint>15 sec</waithint>
<sleeptime>1 sec</sleeptime>
<logpath>{PathToLog}</logpath>
<!--OPTION: logDefines logging mode for logs produced by the executable.Supported modes:* append - Rust update the existing log* none - Do not save executable logs to the disk* reset - Wipe the log files on startup* roll - Rotate logs based on size* roll-by-time - Rotate logs based on time* rotate - Rotate logs based on size, (8 logs, 10MB each). This mode is deprecated, use "roll"Default mode: appendEach mode has different settings.See https://github.com/kohsuke/winsw/blob/master/doc/loggingAndErrorReporting.md for more details -->
<log mode="roll"> </log>
</configuration>

Based on the input you provided, I think the following batch file should work:
call %~dp0win_env/Scripts/activate.bat
uvicorn main:app --port 8590 --host 0.0.0.0
(The %~dp0 resolves to the directory where the batch file is stored, so it works independent of your current working directory.)
Note that the activate.bat does nothing special. It just updates your PATH environment variable and changes the command prompt, which is convenient during development. However, you could also just call the Python executable from your virtual environment without "activating" it. I'm not familiar with uvicorn, but it seems like it can be called as a Python module as well. In that case you could also use the following batch file:
win_env/Scripts/python.exe -m uvicorn main:app --port 8590 --host 0.0.0.0

Related

tkinter.TclError: no display name and no $DISPLAY environment variable python

I want to execute my python file in a remote system using ssh. I exported the file to the remote system.
Here's the sample file:
import os
import time
import pymsgbox
pymsgbox.alert('Hi Afreeth ', 'Welcome')
if 'DISPLAY' not in os.environ:
pass
I want to execute it using ssh from my system and it should display in the remote system.
But it fails
Error i got:
Traceback (most recent call last):
File "cd1.py", line 5, in <module>
File "pymsgbox/__init__.py", line 100, in alert
File "pymsgbox/__init__.py", line 156, in _buttonbox
File "tkinter/__init__.py", line 1871, in __init__
_tkinter.TclError: no display name and no $DISPLAY environment variable
[12113] Failed to execute script myprogram
How to fix it. I found some answers on stack but it doesn't solve me. If i go and execute it in the remote system, it works. But when i execute from my system,it fails. How to fix it.
Found the Answer:
I just need to run export DISPLAY=:0 in their ssh session and programs run will run on the remote display. A quick example:
paulsteven#smackcoders:~$ ssh afreeth#his_ipaddress
afreeth#smackcoders:~$ export DISPLAY=:0
afreeth#smackcoders:~$ firefox
Firefox is now running on afreeth's display.

How do I debug with PyCharm while using Vagrant

I am new to Python. I am new to Vagrant. However, my team runs their project using a Vagrant VM and IDEs of their own choosing. I chose PyCharm, because I've used some JetBrains products in the past.
I'd really like to be able to visually debug through it as it is running. Set a break point, view the values of variables, etc.
PyCharm has a help section (and the related articles above it):
https://www.jetbrains.com/help/pycharm/configuring-product-to-work-on-the-vm.html
I've done all of them, but under Project->Project Interpreter the Path Mappings seem to list all the shared folders on the between the host machine and the Vagrant VM. Those shared folders are
one directory up from the actual project
my vagrant directory
My home directory
I don't think it is pointing to the project or its dependency libraries correctly.
I also get a yellow message at the bottom that says Python packaging tools not found.
If I hit debug, I get the following output in a terminal:
bash: line 0: cd: /vagrant/app: No such file or directory
pydev debugger: process 2032 is connecting
Connected to pydev debugger (build 191.6183.50)
Traceback (most recent call last):
File "/home/vagrant/.pycharm_helpers/pydev/pydevd.py", line 1741, in
<module>
main()
File "/home/vagrant/.pycharm_helpers/pydev/pydevd.py", line 1735, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "/home/vagrant/.pycharm_helpers/pydev/pydevd.py", line 1135, in run
pydev_imports.execfile(file, globals, locals) # execute the script
IOError: [Errno 2] No such file or directory: '/vagrant/app/__main__.py'
It also has opened itself a tab for 'pydev.py' that has in it:
Remote file /home/vagrant/.pycharm_helpers/pydev/pydevd.py is mapped to the
local path C:\Users\<my username>\vagrant\.pycharm_helpers\pydev\pydevd.py
and can't be found. You can continue debugging, but without the source. To
fix that you can do one of the following:
How can setup to debug from PyCharm on my host machine through code running on the Vagrant VM?

Debugging in PyCharm with using Vagrant VM connection - cannot import name to_string

I've encountered an issue where I cannot debug in PyCharm connecting through Vagrant to the VM. This has worked fine for projects up until now. The VM image was recently updated so I'm wondering if that has had an effect. I can run programs in "run" mode, just not debug mode. Here's the error I get
Traceback (most recent call last):
File "/home/vagrant/.pycharm_helpers/pydev/pydevd.py", line 25, in <module>
from _pydevd_bundle import pydevd_vars
File "/home/vagrant/.pycharm_helpers/pydev/_pydevd_bundle/pydevd_vars.py", line 21, in <module>
from _pydevd_bundle.pydevd_utils import to_string
ImportError: cannot import name to_string
Here are the different commands used to run the programs - the first one is debug mode, the second is normal mode
ssh://vagrant#127.0.0.1:2222/usr/bin/python -u /home/vagrant/.pycharm_helpers/pydev/pydevd.py --multiproc --qt-support --client '0.0.0.0' --port 32807 --file /home/vagrant/.pycharm_helpers/pycharm/utrunner.py /vagrant/project/project_test.py::ProjectTest true
ssh://vagrant#127.0.0.1:2222/usr/bin/python -u /home/vagrant/.pycharm_helpers/pycharm/utrunner.py /vagrant/project/project_test.py::ProjectTest true
Any ideas what why to_string is found in normal mode but not debug?
The solution was to delete the /home/vagrant/.pycharm_helpers directory and restart PyCharm and vagrant to regenerate the directory.

airflow startup failed due to gunicorn

Traceback (most recent call last):
File "./python_runtime/bin/airflow", line 15, in <module>
args.func(args)
File "/home/admin/airflow/python_runtime/lib/python2.7/site-packages/airflow/bin/cli.py", line 423, in webserver
'gunicorn', run_args
File "/home/admin/airflow/python_runtime/lib/python2.7/os.py", line 346, in execvp
_execvpe(file, args)
File "/home/admin/airflow/python_runtime/lib/python2.7/os.py", line 385, in _execvpe
func(fullname, *argrest)
OSError: [Errno 2] No such file or directory
I find out that this error was cause by no gunicorn avaiable,so I print all paths in os.py:
/home/admin/airflow/python_runtime/bin/gunicorn
/home/admin/python2.7.2/bin/gunicorn
/home/admin/tools/local/bin/gunicorn
/home/admin/tools/bin/gunicorn
/home/admin/tools/opsdb/gunicorn
/home/admin/odps_tools/dship/gunicorn
/home/admin/php/bin/gunicorn
/home/admin/cmake/bin/gunicorn
/home/admin/jdk1.6.0_24/bin/gunicorn
/home/admin/tools/bin/gunicorn
/usr/kerberos/bin/gunicorn
/usr/local/sbin/gunicorn
/usr/sbin/gunicorn
/sbin/gunicorn
/usr/local/bin/gunicorn
/bin/gunicorn
/usr/bin/gunicorn
/usr/X11R6/bin/gunicorn
while gunicorn exist in this path
/home/admin/airflow/python_runtime/bin/gunicorn
something wrong with my env?
Airflow seems to expect gunicorn in PATH. For my ubuntu instance this fixed it:
$ export PATH=$PATH:~/.local/bin
$ airflow webserver
On MacOS, it wasn't enough with the proposed solution. If I used relative path (with either ~ or $HOME) it didn't work, but using absolute path solved the issue: PATH="${PATH}:/path/to/.venv/bin"
As you can see, I'm using a hidden folder that I created with Python venv, maybe this is connected.
To test it, is not enough to run gunicorn alone, this worked to me with the relative path as well, but which gunicorn returned nothing, and this indicates that airflow webserver will fail to start.

python - compiled calling config file

I'm compiling a python application using pyinstaller.
The structure is like so -
d:\app\myprog.exe
d:\app\config\settings.conf
If I run myprog.exe --switch value from d:\app it runs fine, if I try to run from anywhere else like c:\windows it's not finding my settings.conf file complaining with the message:
Traceback (most recent call last):
File "<string>", line 284, in <module>
File "<string>", line 218, in main
File "ConfigParser.py", line 330, in get
ConfigParser.NoSectionError: No section: 'database'
myApp returned -1
database being the first line in the config file I'm trying to reference.
I'm referencing the BASE_DIR from the app here -
# Global Path and Config Info
try:
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
except NameError: # We are the main py2exe script, not a module
BASE_DIR = os.path.dirname(os.path.abspath(sys.argv[0]))
So that I can get the config file like this -
config = RawConfigParser()
config.read(os.path.join(BASE_DIR, 'config/settings.conf'))
But I guess BASE_DIR is whatever folder I'm running the EXE from (like c:\windows, not the location of the EXE (which is d:\app)?
As mentioned in PyInstaller documentation (in How the One-File Program Works section) when a single executable file (created by PyInstaller) is executed, what happens is that a directory structure of the required library modules (Python VM, libraries and packages, etc.) are extracted from that single executable to a temporary directory, and then the application is started from there.
This means that __file__ in your Python code is not going to be the path to the single executable file, and that's the reason for this issue.
I'd write my app to accept the path to the configuration file from command line arguments, fall back to using an environment variable if available, and then a hard coded default value based on the platform (as most multi platform applications do to reach to their configurations).
Another approach is to use the one-directory output from PyInstaller and include the configuration file in the same directory.
Then to help make it easier to distribute the software to end users, use another tool to create a single Windows installer file from that directory structure. This way you'll be distributing the Windows installer, so users can run to install the application. But when the app runs, it runs from the directory where the configuration file resides.

Categories