Command-line application using setuptools and Anaconda Python - python

I have a Python command line application that I have been distributing on PyPI in the manner described here: https://gehrcke.de/2014/02/distributing-a-python-command-line-application/
In short, that means I'm using setuptools with the entry_points option in my setup.py file:
import programs
setup(
name='my_package',
entry_points={
'gui_scripts': [
'program1 = programs.program1:main',...
]
})
My package is uploaded to PyPI, and can be installed using pip. Normal behavior on the command line is that program1 launches the GUI.
The problem is, I would like to support the Anaconda distribution of Python. If I pip install and try to run program1 using using Anaconda, I get this warning:
This program needs access to the screen.
Please run with a Framework build of python, and only when you are logged in on the main display of your Mac.
The executable script lives here:
~/anaconda2/bin/program1
And here is its text:
#!/Users/***/anaconda2/bin/python
import re
import sys
from programs.program1 import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
And it is importing program1 from this location:
/Users/***/anaconda2/lib/python2.7/site-packages/programs/program1.pyc
How can I get program_1 to run as an executable using Anaconda?

Related

How to create a .exe similar to pip.exe, jupyter.exe, etc. from C:\Python37\Scripts?

In order to make pip or jupyter available from command-line on Windows no matter the current working directory with just pip ... or jupyter ..., Python on Windows seems to use this method:
put C:\Python37\Scripts in the PATH
create a small 100KB .exe file C:\Python37\Scripts\pip.exe or jupyter.exe that probably does not much more than calling a Python script with the interpreter (I guess?)
Then doing pip ... or jupyter ... in command-line works, no matter the current directory.
Question: how can I create a similar 100KB mycommand.exe that I could put in a directory which is in the PATH, so that I could do mycommand from anywhere in command-line?
Note: I'm not speaking about pyinstaller, cxfreeze, etc. (that I already know and have used before); I don't think these C:\Python37\Scripts\ exe files use this.
Assuming you are using setuptools to package this application, you need to create a console_scripts entry point as documented here:
https://packaging.python.org/guides/distributing-packages-using-setuptools/#console-scripts
For a single top-level module it could look like the following:
setup.py
#!/usr/bin/env python3
import setuptools
setuptools.setup(
py_modules=['my_top_level_module'],
entry_points={
'console_scripts': [
'mycommand = my_top_level_module:my_main_function',
],
},
# ...
name='MyProject',
version='1.0.0',
)
my_top_level_module.py
#!/usr/bin/env python3
def my_main_function():
print("Hi!")
if __name__ == '__main__':
my_main_function()
And then install it with a command such as:
path/to/pythonX.Y -m pip install path/to/MyProject

Building and distributing python moduel using rpm

I am trying to build and distribute rpm package of python module for centos. I have followed following steps
created virtualenv and installed requires
in module added setup.py with install_requires.
then using python2.7 from virtualenv build package
../env/bin/python2.7 setup.py bdist_rpm
Now I got src, no-arch and tar-gz files in 'dist' folder.
foo-0.1-1.noarch.rpm, foo-0.1-1.src.rpm, foo-0.1.tar.gz
I tried to install package src-rpm using 'sudo yum install foo-0.1-1.src.rpm',
got error something like wrong architecture
Then I tried to install package no-arch, 'sudo yum install foo-0.1-1.noarch.rpm' it works smoothly.
But after running script, it gave some import error. here I expect to download that module automatically.
The last thing is I am using some third party library which is not on pip.
So I want to whole setup using virtualenv with required modules. So after installing rpm, user can run script directly instead of installing third party libs separately and explicitly.
Some above steps may sounds wrong, as I am new to this stuff.
Following is code in setup.py
from setuptools import setup, find_packages
setup(
name = "foo",
version = "0.1",
packages = find_packages(),
scripts = ['foo/bar.py', ],
# Project uses reStructuredText, so ensure that the docutils get
# installed or upgraded on the target machine
install_requires = ['PyYAML', 'pyOpenSSL', 'pycrypto', 'privatelib1,'privatelib2', 'zope.interface'],
package_data = {
# If any package contains *.txt or *.rst files, include them:
'': ['*.txt', '*.rst'],
# And include any *.msg files found in the 'billing' package, too:
'foo': ['*.msg'],
},
# metadata for upload to PyPI
author = "foo bar",
description = "foo bar",
license = "",
keywords = "foo bar",
# could also include long_description, download_url, classifiers, etc.
)
Also I am using shebang in script as,
#!/usr/bin/env python2.7
Note:
I have multiple python setups. 2.6 and 2.7
By default 'python' commands gives 2.6
while command 'python2.7' gives python2.7
output of `'rpm -qp foo-0.1-1.noarch.rpm --requires' =>
`/usr/bin/python
python(abi) = 2.6
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
When i install pakcage. script's shebang line (which is now '/usr/bin/bar.py') is getting changed to /usr/bin/python' But I exclusively want to run script on python2.7.
Thanks in advance

how to import a python module before installing it?

So I'm trying to create a setup.py file do deploy a test framework in python.
The library has dependencies in pexpect and easy_install. So, after installing easy_install, I need to install s3cmd which is a tool to work with Amazon's S3.
However, to configure s3cmd I use pexpect, but if you want to run setup.py from a fresh VM, so we run into an ImportError:
import subprocess
import sys
import pexpect # pexpect is not installed ... it will be
def install_s3cmd():
subprocess.call(['sudo easy_install s3cmd'])
# now use pexpect to configure s3cdm
child = pexpect.spawn('s3cmd --configure')
child.expect ('(?i)Access Key')
# ... more code down there
def main():
subprocess.call(['sudo apt-get install python-setuptools']) # installs easy_install
subprocess.call(['sudo easy_install pexpect']) # installs pexpect
install_s3cmd()
# ... more code down here
if __name__ == "__main__":
main()
I know of course I could create a another file, initial_setup.py to have easy_install and pexpect installed, before using setup.py, but my question is: Is there a way to import pexpect before having it installed? The library will be installed before using it, but does the Python interpreter will accept the import pexpect command?
It won't accept it like that, but Python allows you to import things everywhere, not only in the global scope. So you can postpone the import until the time when you really need it:
def install_s3cmd():
subprocess.call(['easy_install', 's3cmd'])
# assuming that by now it's already been installed
import pexpect
# now use pexpect to configure s3cdm
child = pexpect.spawn('s3cmd --configure')
child.expect ('(?i)Access Key')
# ... more code down there
EDIT: there is a peculiarity with using setuptools this way, since the .pth file will not be reloaded until Python relaunches. You can enforce reloading though (found here):
import subprocess, pkg_resources
subprocess.call(['easy_install', 'pexpect'])
pkg_resources.get_distribution('pexpect').activate()
import pexpect # Now works
(Unrelated: I'd rather assume that the script itself is called with the needed privileges, not use sudo in it. That will be useful with virtualenv.)

Help building a mac application from python using py2app?

I have a Tkinter app written in python, and I want to make "native" (easy to run) mac and windows executables of it. I've successfully built a windows .exe using py2exe, but the equivalent process with py2app isn't working.
Here's my setup.py:
from setuptools import setup
import sys
MAIN_SCRIPT = "myapp.py"
WINDOWS_ICON = "myicon.ico"
MAC_ICON = "myicon.icns"
if sys.platform in ("win32", "win64"): # does win64 exist?
import py2exe
setup( windows=[{ "script":MAIN_SCRIPT,
"icon_resources":[(0x0004, WINDOWS_ICON)]
}],
)
elif sys.platform == "darwin":
import py2app
setup( app=[MAIN_SCRIPT], # doesn't include the icon yet
setup_requires=["py2app"],
)
I just cd to my app directory and run python setup.py py2app. The .app appears without errors, but it crashes on launch with "myapp has encountered a fatal error, and will now terminate."
I'm running Snow Leopard, and I've tried this with both the standard Apple Python 2.6 and python25 from MacPorts. I read somewhere that it's better to use a different Python because py2app won't bundle the system version in your app.
EDIT: Here's what the mac console has to say about it:
11/27/10 1:54:44 PM [0x0-0x80080].org.pythonmac.unspecified.myapp[77495] dlsym(0x10b120, Py_SetProgramName): symbol not found
11/27/10 1:54:46 PM [0x0-0x80080].org.pythonmac.unspecified.myapp[77495] 0x99274242
11/27/10 1:54:46 PM com.apple.launchd.peruser.501[185] ([0x0-0x80080].org.pythonmac.unspecified.myapp[77495]) Exited with exit code: 255
Turns out it was a problem with using Snow Leopard. I tried it on a Leopard machine at school and it builds fine.

How to install python module as a command line application under windows?

I need to install a python module in the site packages that also will be used as a command line application. Suppose I have a module like:
app.py
def main():
print 'Dummy message'
if __name__ == '__main__':
main()
setup.py
import distutils
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
if __name__ == '__main__':
setup(name = 'dummy',
version = '1.0',
packages = ['dummy'],
)
Creating the dist by:
setup.py sdist
Install:
setup.py install
And now I would like to use it as a command line application by opening the command window and typing just: dummy
Is it possible to create such application under windows without to carry out registering system pat variables and so on ...
You can use the options in setup.py to declare command line scripts. Please refer to this article. On Windows, the script will be created in "C:\Python26\Scripts" (if you didn't change the path) - lots of tools store their scripts there (e.g. "easy_install", "hg", ...).
Put the following in dummy.cmd:
python.exe -m dummy
Or is it dummy.app...
Oh well, it's one of those.

Categories