I'm writing a Python application that is executable. It reads and writes to a file. The application uses wx for a GUI and has been given the following permissions:
chmod +x app.py
When I load the application from the terminal like so:
./app.py
The application loads and causes no errors.
However, when I double click the app.py file and click 'execute', everything works perfectly except for the reading and writing of this file. This is a major part of the program and causes errors.
I cannot, for the life of me, understand why this is not working.
I have attempted to set it so that it loads as the root user each time with no luck. I have also been developing as the root user the entire time, so I shouldn't see any issues.
I am using the default Raspbian OS.
It sounds like you need to modify the permissions of the file to be readable/writable/executable by the user you log into the GUI with. Do some reading on Linux File Permissions and see where that takes you.
Related
im working on a small ETL that collects data using webscraping, cleans and manipulates it and sends to a local sqlite3 database.
If i execute the command /virtualenv_path/python /script_path/script.py it runs perfectly, but if i schedule this command with crontab it does not work.
It just does not send any data. However, my log file shows me that the crontab is executing script.py using my venv as expected.
So, what is going on? What should i do to solve this?
I suppose that my script is not incorrect because if i execute without crontab it works flawlessly and even with crontab it does not show any error (as i said, log file suggests that everything is going really well)
this is my repository: https://github.com/raposofrct/wescraping-ETL
there we have ETL folder that contains my script, crontab command that im using and my sqlite database.
thanks for any help or clue that you guys can give me.
Your script is likely working, but it's not putting data into the database file you're looking at. hm_db.sqlite is relative to whatever the current working directory is:
DataBase(dados,create_engine('sqlite:///hm_db.sqlite',echo=False))
That is very unlikely to be the same directory you are in when you run the script manually. Either provide an absolute path or make the path relative to your script directory, e.g.
from pathlib import Path
root_directory = Path(__file__).parent
database_file = root_directory / "hm_db.sqlite"
DataBase(dados, create_engine(f"sqlite:///{database_file}", echo=False))
Alternatively, log os.getcwd() in your existing script to figure out where your cronjob has been storing data.
I'm asking help today because I'm new to Tkinter and Pyinstaller (and python in general) and I'm having troubles with it.
I have a simple app working with sqlite, tkinter and pyinstaller to compile all of this in an executable program, the entrance point of my program is a file named main.py
This file calls all the dependancies (like the sqlite module for python, tkinter and my other files like classes etc...)
I made a very simple interface, with a Hello World in a tkinter label and a button to go to page 2 which displays page2 (also in a label), just to see if I'm capable of making it all run and compile all of these pieces together.
I can run it throught my shell executing it like : python main.py and everything is working fine.
But when I run pyinstaller on my linux machine, and start executing the program, nothing appears, my database.db (sqlite database file) is created but I don't have any interface like when I run it with my shell. The thing is getting even worse on windows where, once I've my .exe it just opens a shell and crash after few seconds, not even creating the database.
What I did is I created a 'log file', in which I write the steps of the program.
As you can see on the following picture, the 2 first prints are wrote in my log file (on linux), so I think it crashes when I try to create the window.
If any of you have an idea on what I do wrong, I would really appreciate help :)
General
From the PyInstaller manual:
Before you attempt to bundle to one file, make sure your app works correctly when bundled to one folder. It is is much easier to diagnose problems in one-folder mode.
As the comments suggested, use a catch-all try/except block to log all exceptions to a file. That is probably the best way to see what is really happening. Make sure that the logfile is created in an existing location where you have the necessary permissions.
I would suggest to take advantage of the built-in logging module instead of creating your own. It can e.g. automatically add from which file a log line was created.
IMHO, it is probable that the failures on Linux and ms-windows have completely different causes. You should probably treat them as different issues.
Linux
When you use single file mode, that file is unpacked into a temporary folder, probably somewhere in /tmp. Some Linux distributions mount the /tmp filesystem with the noexec flag. This is incompatible with PyInstaller.
ms-windows
On windows, there are basically two different Pythons; python.exe and pythonw.exe. Basically it is one of the quirks of windows that this is necessary. The latter is for GUI programs like tkinter programs. A tkinter script should not show a cmd window. So I'm guessing that PyInstaller calls your command with python.exe instead of pythonw.exe. From the manual:
By default the bootloader creates a command-line console (a terminal window in GNU/Linux and Mac OS, a command window in Windows). It gives this window to the Python interpreter for its standard input and output. Your script’s use of print and input() are directed here. Error messages from Python and default logging output also appear in the console window.
An option for Windows and Mac OS is to tell PyInstaller to not provide a console window. The bootloader starts Python with no target for standard output or input. Do this when your script has a graphical interface for user input and can properly report its own diagnostics.
As noted in the CPython tutorial Appendix, for Windows a file extention of .pyw suppresses the console window that normally appears. Likewise, a console window will not be provided when using a myscript.pyw script with PyInstaller.
Also, on windows it can matter which Python distribution you're using. I used to be a fan of Anaconda, but lately I've come to prefer the python.org version because it gives me less headaches. On anaconda Python I had the problem that tkinter programs would not launch without showing a cmd window, whatever I tried. Only switching to python.org Python solved that problem.
To preface, I've read other threads on the topic, but all their solutions don't work for me.
I have a small .sh file that just runs python3 foo.py. I used a script to turn this file into a .app file, but when I try to open it, I can see the app begin to appear in the dock and then disappear. However, when I open the file inside of the Unix executable itself in Terminal, all is well.
I have tried:
Changing the shebang in the .sh file to both #!/usr/bin and #!/urs/bin/env
Creating an empty .plist file
Making sure every file has execute permissions
Oddly enough, running open appname.app gives the following:
LSOpenURLsWithRole() failed with error -10810 for the file /Users/blah/blah/Lofi.app.
Thanks in advance
When you say you've read other threads on the topic, and the solutions don't work, does that mean you tried every thing in the comments under the sh-to-app script? There are a couple of specific fixes enumerated there.
What OS are using? Looks like higher OS needs you to register the app with the OS.
Check permissions of your personal shell script
Does it open in Terminal with open APP.app? I think you're saying it does. You can look at the last comment under the the sh-to-app script for possibly helpful instructions.
Not so much an answer, more of a workaround. I ended up taking the APP.app/Contents/MacOS/APP executable and creating an application in Automator that simply runs the file, and saving that process as an application in the Applications folder.
I have a Python script that should open my Linux terminal, browser, file manager and text editor on system startup. I decided crontab is a suitable way to automatically run the script. Unfortunately, it doesn't went well, nothing happened when I reboot my laptop. So, I captured the output of the script to a file in order to get some clues. It seems my script is only partially executed. I use Debian 8 (Jessie), and here's my Python script:
#!/usr/bin/env python3
import subprocess
import webbrowser
def action():
subprocess.call('gnome-terminal')
subprocess.call('subl')
subprocess.call(('xdg-open', '/home/fin/Documents/Learning'))
webbrowser.open('https://reddit.com/r/python')
if __name__ == '__main__':
action()
here's the entry in my crontab file:
#reboot python3 /home/fin/Labs/my-cheatcodes/src/dsktp_startup_script/dsktp_startup_script.py > capture_report.txt
Here's the content of capture_report.txt file (I trim several lines, since its too long, it only prints my folder structures. seems like it came from 'xdg-open' line on Python script):
Directory list of /home/fin/Documents/Learning/
Type Format Sort
[Tree ] [Standard] [By Name] [Update]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
/
... the rest of my dir stuctures goes here
I have no other clue what's possible going wrong here. I really appreciate your advice guys. thanks.
No, cron is not suitable for this. The cron daemon has no connection to your user's desktop session, which will not be running at system startup, anyway.
My recommendation would be to hook into your desktop environment's login scripts, which are responsible for starting various desktop services for you when you log in, anyway, and easily extended with your own scripts.
I'd do as tripleee suggested, but your job might be failing because it requires an X session, since you're trying to open a browser. You should put export DISPLAY=:0; after the schedule in your cronjob, as in
#reboot export DISPLAY=:0; python3 /home/fin/Labs/my-cheatcodes/src/dsktp_startup_script/dsktp_startup_script.py > capture_report.txt
If this doesn't work, you could try replacing :0 with the output of echo $DISPLAY in a graphical terminal.
I'm making a chat client for OSX, and I wanted it to be able to run as both a .app (for my less technologically inclined users) and as a .py file. I made a workflow app that contained two .py files (an auto-updater and the client itself), run by a python script in the .wflow file. This worked well. However, I couldn't update the updater or workflow script, and the icon was the Python rocket instead of the icon I had chosen. Then, I combined the client .py file with the updater .py file. This still worked, and now I could update the updater. I still couldn't update the python script in the workflow, though, and the icon was still wrong. So, I modified the updater to open the .wflow file, split it into a list (based on python comments in the workflow's python script, such as "#Start") of the stuff before the script, the script's modification time, and the stuff after the script. If the modification time isn't the same as the modification time of the remote file (the one that the updater updates from), then the script downloads the remote .py file, replaces characters (<, >, &) that .wflow files replace ('<' -> "<"), and opens document.wflow with the "w" (write/replace) flag. Then, the stuff that was before the old script, the downloaded script, and the stuff that was after the old script (using file.write(''.join(list))) are all put into document.wflow. This should work, but OSX no longer sees document as an automator file.
As you can see, OSX thinks that the old file is a Workflow, while the new file is a "Microsoft Excel 97-2004 workbook". The IMClient.app (the application that contains document.wflow) gives this message when I try to run it: "The document "IMClient" could not be opened because it is damaged or incomplete." Does anyone know how to fix this?
I'm using python 2.7 and OSX 10.7. The updater is downloading files via FTP.
If clarification is necessary, just ask. I'll post the working and nonworking files if anyone wants them.
EDIT: the file command gives "document.wflow: XML document text" for both the old and new file.