No file creation with logging module in py2app mac application - python

I've got a python script that uses the logging module to create a log file. Using the following line:
logging.basicConfig(filename='debug.lg',filemode='w', level=logging.DEBUG)
This works great as a script. After compiling with py2app the log file is no longer created.
If I change the above line to,
logging.basicConfig(format = '%(levelname)s:%(message)s', level=logging.DEBUG)
and then force the console window open i get the expected logging printout. This tells me the logging module is working in my app.\
I anticipate this is some permission or virtual environment issue.
How do I make my log file be created (in the same directory that the app exists)

The mac app appears to run in a virtual environment. I can force the app to run with a console window open and print sys.argv[0] I see that I'm four folders deep in my .app file. This is where the log file is being created. I'm unable to navigate here in finder. If i set the absolute path of the log file four folders up (the location of the .app file) the log file stays after execution.

Related

CWD in vsCode / sqlite3

I created a workspace in vsCode at path/to/workspace and started using sqlite3.connect("data.db"). My first database would be created correctly - but after doing so again in another folder path/to/workspace/subfolder ,
sqlite3.connect("data.db") would still connect to the db at path/to/workspace.
os.path.abspath(".") returns path/to/workspace in the scripts of both directories, so the cwd just remains the directory of the workspace.
(1) Why is the cwd of an executed script not the path to the script but rather the path to the workspace? / Why doesn't sqlite3 simply connect to databases relative to the path to the script that is executed?
I found that I can solve that with os:
path = os.path.dirname(__file__)
con = sqlite3.connect(path + "\data.db")
(2) Is that approach a safe way to handle that problem also considering the portability of a project?
Which cwd you get in the script depends on the cwd in the terminal, in other words, the routs in the terminal where you execute your script. For example:
If you want to change the route to the parent folder of the script you want to execute when you create a new terminal, you can add this in the settings.json file:
"terminal.integrated.cwd": "${fileDirname}",
But it does not work when you execute the command of Run Python File in Terminal, because the terminal was created by the Python extension, you can add this in the settings.json file to achieve it:
"python.terminal.executeInFileDir": true,
And you can add this in the launch.json file to modify the route in debugging mode:
"cwd": "${fileDirname}"
But both of the above methods were not recommended, Remain the cwd to the workspace can make the structure clearly.

Python/Jupyter getting a FileNotFoundError when attempting to read an excel file however said file is in the correct directory

data = pd.read_excel("ETH-USD")
I continually receive an error message informing me that the file cannot be found
this is despite the fact that
1: my directory has been changed within to Python to the same address as the folder where the excel file is stored
2: the file name is input exactly as displayed
Any ideas on why it is unable to find my file?
Is it possible that the excel file has an extension of .xlsx, but your file explorer is set to "hide file extensions"? Try:
data = pd.read_excel("ETH-USD.xlsx")
Or, see what's in the current directory by running:
import os
print(os.listdir())
A tip from the comments:
Windows tip too: hold Shift, right click the excel file and copy as path, then you can see its path (if you don't enable viewing file extensions in the file browser). –
creanion
Often when running python scripts from compilers the "working directory", or where you are running the script from doesn't match the location of your script, hence why I find it much more reliable to use this instead:
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
data = pd.read_excel(os.path.join(BASE_DIR,"ETH-USD")
To add, while I do not use Jupyter, in VSCode which I use, the working directory (which is where python looks for if you put a path in read_excel() but its not a full path) is often the current directory opened in there, so I expect a similar issue to be the reason for your issue.

While running Python application in EXE I get .. 'vba_extract.py' is not recognized

I've created an .EXE file from Python scripy using pyinstaller.
Part of the program should get xlsm file and extract its VBA to bin file. I pass the xlsm file to the EXE using the .spec file:
datas=[('gen_ClipFile_V3p1.xlsm','.')],
Then, when the program gets to extract the 'vbaProject.bin' out of the xlsm file
I get the error:
'vba_extract.py' is not recognized as an internal or external command
My relevant code:
import xlsxwriter
import os
from pathlib import Path
# a function called by tkinter file open
def compareDesigns(self):
# find the EXE temporary working directory path
bundle_dir = Path(getattr(sys, '_MEIPASS', Path.cwd()))
strbundle_dir = str(bundle_dir)
XLSMtoExtract = os.path.join(strbundle_dir, 'gen_ClipFile_V3p1.xlsm')
os.system("vba_extract.py" + XLSMtoExtract)
My spec file includes:
datas=[('gen_ClipFile_V3p1.xlsm','.')],
hiddenimports=['matplotlib', 'pathlib', 'time', 'sys', 're', 'operator', 'numpy', 'mplcursors', 'collections', 'xlsxwriter', 'os', 'tkinter', 'pyinstaller'],
I do manage to run the application on my machine, but other users with different machines reports this error.
I believe that I should find vba_extract.py path in the exe temporary area and reference to it but I do know how to that.
If xlsxwriter is installed correctly then vba_extract.py should be added to the Windows %PATH%. However, that may not be available in the same environment your main script is running in.
Some suggestions, in reverse order of recommendation:
Figure out the path issue.
Ignore the path issue and include the vba_extract.py code directly in your program. It isn't very big and you could leave out a lot of the exception handling if you know the target xlsm file is okay.
Ignore the macro extraction part and just ship the VBA macro with the code. This may also lead to path issues however.
You could also store the macro is hex/text format in your program and convert it back to a binary file, on the fly.

Python app in autorun doesn't open file

I created an application that is running at windows startup, but every time it give me an Error:
[Errno 2] No such file or directory: 'user'
that error happen only at startup, if I open it normally (with doubleclick) it works good.
Note: I created the .exe with Pyinstaller and the file called 'user' is in the same directory of .exe (Program Files/App1/main.exe)
Maybe autorun works like a temp folder that can't recognize the content of Program Files directory?
Your program should never count on the current working directory being the same as the directory it's run from. If the user runs your program from the command line, or you put it in a batch file, or you launch it from autorun, or another program tries to run it… in all those cases, the working directory will be somewhere else.
sys.argv[0] gives you the path to your program. So:
import sys
import os
scriptdir = os.path.dirname(os.path.abspath(sys.argv[0]))
userpath = os.path.join(scriptdir, 'user.exe')

Crontab Python Script Execution (Can't find settings config file)

My Crontab -l
# m h dom mon dow command
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
00 8,20 * * * python /home/tomi/amaer/controller.py >>/tmp/out.txt 2>&1
My controller.py has config file settings.cfg also it uses other script in the folder it's located (I chmoded only controller.py)
The error
1;31mIOError^[[0m: [Errno 2] No such file or directory: 'settings.cfg'
I have no idea how to fix this? Please help me?
Edit: The part that read the config file
def main():
config=ConfigParser.ConfigParser()
config.readfp(open("settings.cfg"),"r")
As I initially wrote in my comment, this is because you are using relative path to the current working directory. However, that is not going to be the same when running all this via the cron executable rather than the python interpreter directly via the shebang.
Your current code would look for the "settings.cfg" in the current working directory which is where the cron executable resides, and not your script. Hence, you would need to change your code logic to using absolute paths by the help of the "os" built-in standard module.
Try to following line:
import os
...
def main():
config = ConfigParser.ConfigParser()
scriptDirectory = os.path.dirname(os.path.realpath(__file__))
settingsFilePath = os.path.join(scriptDirectory, "settings.cfg")
config.readfp(open(settingsFilePath,"r"))
This will get your the path of your script and then appends the "settings.cfg" with the appropriate dir separator for your operating system which is Linux in this particular case.
If the location of the config file changes any time in the future, you could use the argparse module for processing a command line argument to handle the config location properly, or even without it simply just using the first argument after the script name like sys.argv[1].
Your code is looking for settings.cfg in its current working directory.
This working directory will not be the same when cron executes the job, hence the error
You have two "easy" solutions:
Use an absolute path to the config file in your script (/home/tomi/amaer/config.cfg)
CD to the appropriate directory first in your crontab (cd /home/tomi/amaer/ && python /home/tomi/amaer/controller.py)
The "right" solution, though, would be to pass your script a parameter (or environment variable) that tells it where to look for the config file.
It's not exactly good practice to assume your config file will always be lying just next to your script.
You might want to have alook at this question: https://unix.stackexchange.com/questions/38951/what-is-the-working-directory-when-cron-executes-a-job

Categories