Convert a script into macOS application? - python

I have been looking up how to convert a .py script into an .app application so the users know how to run it. So far I have only found using py2app or pyinstaller. Is there a significant disadvantage using an application generated by exporting the following script into application and putting my python script into the application's resource folder? (My python script has a GUI and only uses a built-in library in python 2.7.)
tell application "Finder"
if exists POSIX file "/Applications/app.app/Contents/Resources/appname.py" then
tell application "Terminal"
do script "python /Applications/app.app/Contents/Resources/appname.py"
end tell
else if exists POSIX file "/Volumes/appname/appname.py" then
tell application "Terminal"
do script "python /Volumes/appname/appname.py"
end tell
else
display dialog "Please copy the file to the Application folder, or mount the installation diskimage"
end if
end tell
tell application "Terminal"
close
end tell
It works fine on my computer, so I am just curious why I couldn't find it on the Internet.

There are two things I would advise.
Use path to current application so that you have the path no matter
where the app is.
What may be "cleaner" is, instead of using the Terminal, use do shell script like:
do shell script "/path/to/my/script/script.py"
as long as the script is "chmod"-ed to be executable (I also like using a utility called "Kilometre" for this)
Apart from that, there's nothing dangerous or wrong about what you're trying to do.

Related

Tkinter program compiled with pyinstaller crash on launch

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.

python or pythonw in creating a cross-platform standalone GUI app

I am developing a simple standalone, graphical application in python. My development has been done on linux but I would like to distribute the application cross-platform.
I have a launcher script which checks a bunch of environment variables and then sets various configuration options, and then calls the application with what amounts to python main.py (specifically os.system('python main.py %s'% (arg1, arg2...)) )
On OS X (without X11), the launcher script crashed with an error like Could not run application, need access to screen. A very quick google search later, the script was working locally by replacing python main.py with pythonw main.py.
My question is, what is the best way to write the launcher script so that it can do the right thing across platforms and not crash? Note that this question is not asking how to determine what platform I am on. The solution "check to see if I am on OS X, and if so invoke pythonw instead" is what I have done for now, but it seems like a somewhat hacky fix because it depends on understanding the details of the windowing system (which could easily break sometime in the future) and I wonder if there is a cleaner way.
This question does not yet have a satisfactory answer.
If you save the file as main.pyw, it should run the script without opening up a new cmd/terminal.
Then you can run it as python main.pyw
Firstly, you should always use .pyw for GUIs.
Secondly, you could convert it to .exe if you want people without python to be able to use your program. The process is simple. The hardest part is downloading one of these:
for python 2.x: p2exe
for python 3.x: cx_Freeze
You can simply google instructions on how to use them if you decide to go down that path.
Also, if you're using messageboxes in your GUI, it won't work. You will have to create windows/toplevels instead.

Blender 2.7 MacOS console error

I'm using Blender 2.7 on my mac (OS 10.9.2) and the console won't properly open. If I open blender.app/Contents/MacOS/blender, I get a new terminal window, but it's full of a mix of legible and illegible characters such as "œ˙Ì˛Ä&àÖÄH__PAGEZERO__TEXTÃÃ". No print statements or errors will log there from Blender, either.
Anyone know what's going on?
Thanks!
Edit: I'm also new to terminal and was trying to use "open blender" from the /Contents/MacOS directory :P. If you type "./blender" from the parent directory, it works just fine.
If anyone could shed some light on what's happening or what the difference between typing "./filename" and "open filename" is, that would be awesome.
Blender has various resources it needs to run that are located in the same folder as the binary, it starts with the current working directory to find them when you start blender.
In the terminal you are typing commands, there is a sequence (defined in the PATH variable) to where the command is searched for, prefixing the command with ./ is saying to run the command in the current working directory instead of searching through the PATH list for it.
The command open is meant to open editable files in a suitable editor, it would appear that it gets the idea that it can be handled with the terminal, except the new terminal will start in your home directory leaving blender unable to find it's resources. It's been a few years since I used OSX but it may also be trying to run the blender binary as a shell script. Either way open doesn't handle runnable binaries and isn't designed to.
So the difference is that open blender is like saying that you want to edit the file, but ./blender is actually running an application from the command line.
You may also find it fairly easy to create an applescript that tells the terminal to change the working directory and start blender. This can easily be saved as an application you can start from the finder. Which I think would be (untested) -
tell application "Terminal"
do script "cd /Applications/blender/blender.app/Contents/MacOS && ./blender"
end tell
And if all you want is the python output when you run your scripts you may want to try the script here - it lets you run a script in blender's python console to catch the output.
When you want blender specific help with python scripting ask at blender.stackexchange
Sorry if this answer isn't quite to your question, but having to do with the subject:
listen up all mac users, here is something for you:
with my own "getting annoyed" experience and help from the idea of this guy (sambler) I made a simple app for the purpose of opening blender with terminal.
---Please try it, it is easy to install and super handy---
here is the application, if you want it and here...
..is how to use it:
Navigate yourself to blender.app with finder.
Right click on blender and select "Show Package contents".
Download the app and unzip it.
Drag the app into blender's "Contents" folder.
Drag the app to dock and open for the first time.
(optional) Dance around the room and sing about how fortunate you are to have such an app.
Alternatively here is the applescript source: (currently, with plenty of helpful comments)
set myPath to ((path to current application) as string) --find the path to blenderOpen.app
set myPath to ((characters 1 through ((length of myPath) - 1) of myPath) as string) --rip off the last ":"
set charDelete to (last character of myPath) -- rip off the "blenderOpen.app"
repeat until charDelete = ":" -- rip off the "blenderOpen.app"
set myPath to ((characters 1 through ((length of myPath) - 1) of myPath) as string) -- rip off the "blenderOpen.app"
set charDelete to (last character of myPath) -- rip off the "blenderOpen.app"
end repeat
set myPath to myPath & "MacOS" --find the blender runtime by appending this path
set myPath to quoted form of the POSIX path of myPath -- convert path so terminal understands
(*
why this little if statement down below?
This if statement is here because if a user
opens terminal and runs some command,
then afterwards runs our script,
we want to use a new window so as not
to interfere with the user.
However, if WE open terminal,
than we want to use the window
that terminal just made for us.
*)
if testterminal() then
tell application "Terminal" to do script "cd " & myPath & " && ./blender" -- tell terminal to open new window, and open blender, Voila!!!
else
tell application "Terminal" to tell front window to do script "cd " & myPath & " && ./blender" -- tell terminal to open blender, in the current window, Voila!!!
end if
return myPath
on testterminal()
tell application "System Events" to (name of processes) contains "Terminal"
end testterminal

Easy way to launch Python scripts with the mouse in OS-X

I'd like to write cross platform Python scripts that are GUI frontends for command line programs. The problem is I know a few Mac users who think that using the terminal will have the same effect as throwing their computer off the top of a skyscraper. In Linux and Windows it's easy enough to setup a Python script so the user can double click an icon and the script will start without opening any extra windows. Is there an easy way to do this with OS-X? Would the user have to install a different Python than the one that comes with OS-X? I haven't been able to find a definitive answer.
You might want to look at Platypus. It's a freeware app for generating apps which wrap scripts.
Another way to do something like that is using Automator or even AppleScript Editor. Either can produce an application which just runs a script.
Update:
For Automator: Launch Automator, select the Application template, type "script" in the search field, double-click Run Shell Script, switch the shell pop-up menu to /usr/bin/python, type/paste your Python script into the text field. Or, leave the pop-menu on /bin/bash and just write an invocation of an external script in the text field. Save as an application.
You can also view help from its Help menu.
For AppleScript, launch AppleScript Editor, type the following as the script:
do shell script "/usr/bin/true"
Replace /usr/bin/true with the path to whatever script you like. Save as an application.
Again, there's help in the Help menu.
py2app does this with aplomb. You make your Python script, use whatever dependencies you need (wx, Tkinter, etc.) and py2app makes you a standalone app bundle that will run in any modern OS X environment. It bundles Python too, so you can use any Python you want (not just the system default).
The downside is that the generated apps might be large, up to 50MB if you have a lot of dependencies (though that is somewhat of an extreme).
There are two ways to do this:
Click on a script.
Press command-i to open the "get info" window.
Expand the "Open With" section (if it isn't already).
Choose "Python Launcher" from the drop-down menu.
Click "Change All" if you would like ALL Python scripts to launch when double clicked.
Possibly open Python Launcher and uncheck "Run in a Terminal window"
This will work for this machine only, so it is less portable than the following. Why? Because the default for opening a document type varies depending on what is installed (XCode and/or IDLE will both take over opening a .py file).
Method Two:
Validate the Interpreter Directive, that's the first line of the file. I suggest using /usr/bin/env python3. This will run the first python3 interpreter that is on the users path.
Make the script executable chmod a+x <script_name> from the Terminal.
Change the extension from .py to .command (this will be opened by the Terminal).
Use zip or tar for distribution so that the permissions do not get mangled.
This method will open a Terminal window, but when the Python window is closed the terminal window will also close.
If your script has dependencies outside of the standard library, then you should provide a second .command file to install those. This may make things more complicated, but using pip3 install --user <list of dependencies> should minimize complications.

How to auto-run a script

I created a script that will tell me what to wear in the morning based on the weather (i.e. rain slicker if it will rain, heavy jacket if it will be cold, etc). I have fairly basic programming experience with python and the script works perfectly, but I want to be able to create a file that I can just double-click from my desktop and the script will automatically run.
My goal is to be able to simply double click [something] in the morning and it will automatically run the script and thus tell me what to wear. How could I go about doing this?
System Specifications:
python
Mac OSX
This worked for me on Snow Leopard:
-Put the python script on the desktop.
-Right click on the script file, and choose "Get info"
-Find "Open With", and choose "Python Launcher" from the dropdown box
Now double-clicking the script file will run the script in a new terminal window.
I'm not sure what versions of OS X come with the Python Launcher application. If you don't have that, you can solve it with a couple extra steps:
-Put the python script anywhere
-Create a shell script on the desktop with one line:
python "/Users/john/scripts/what-to-wear.py"
(Where I've assumed your script is called what-to-wear.py and is in /Users/john/scripts. Be aware that you do need to use an absolute path.)
-Make the shell script executable. In a terminal:
chmod 755 what-to-wear-shell-script
-Double clicking the shell script should run it in a terminal, running your python script.
What you want to do is create an executable file.
I've never used a Mac or Python, but look at this question and the first answer:
How can I create a directly-executable cross-platform GUI app using Python?
Seems http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html is what you're looking for
Use a batch file to make it automatic
Example :
1. Open Notepad -> type the following.
This one's for Windows..It might give you a hint
:start
C:\Python34\python.exe(your python file location)Your *.py file location.
:end
Save this with a *.bat extension
That's it ..you can configure more on this batch,I guess batch is the automation for day to day script
In Linux/unix based OS , add #!/usr/bin/python3 line on top of your script file with extension .py , if you have python version 3. Or change it to the version installed in the machine
Further , make the file executable by
sudo chmod +x <fileName>
for windows, add windows python path and make the file executable
You want the script to download the weather information online and output the clothes based on your predefined rules?
If this is the case, use urllib to download the page and do some ad hoc parsing over the downloaded html page to get the whether information. And write your logic using nested IF THEN ELSE blocks.

Categories

Resources