0

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>
Manuel
  • 649
  • 5
  • 22
  • If you call the application without activating the virtual environment, do you really get the _exact_ same error message? So it can find `sqlite3` but fails to load `_sqlite3` due to the DLL load error? And is `{Path}\scoop\apps\anaconda3\current\` your main environment? – wovano Mar 15 '22 at 11:32
  • So I can not really tell if something has changed which I am missing or if I had some sort of typo in there before, but for some reason the .bat file ```call uvicorn main:app --port 8590 --host 0.0.0.0``` now works without a problem... When I try to create a Windows service with this small bat file it fails because uvicorn is not installed. So it seems that my error anaylsis was wrong and something else is the problem. – Manuel Mar 15 '22 at 12:11

1 Answers1

0

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
wovano
  • 4,543
  • 5
  • 22
  • 49
  • @Manuel, how did you come to the conclusion that the main environment was used? Could you add the relevant information to your question? I'm pretty sure that it _should_ work like this... – wovano Mar 14 '22 at 16:12
  • @wovona, ok now both bat files work (but i still get the same error when i deploy them as a service). – Manuel Mar 15 '22 at 10:10