I have build a small quiz using Tkinter in Python and I wish to release the game for all to play, so that people can just pip install and play the game.
I have gone through the docs to release a PyPi package, I released one, it gets successfully installed. However, I'm unable to launch the application from commandline nor can I look for the binary. I don't know where am I going wrong. Please help me out here.
My setup.py file looks like this
from setuptools import setup
from codecs import open
from os import path
here = path.abspath(path.dirname(__file__))
with open(path.join(here, 'README.rst')) as f:
long_description = f.read()
setup(
name='py-quiz',
version='0.1.1',
description='Python based Quiz game.',
long_description=long_description,
author='Abhijit Nathwani',
author_email='abhijit.nathwani#gmail.com',
LICENSE='MIT',
url='https://github.com/abhijitnathwani/PyQuiz',
keywords='pyquiz tkinter'
)
To package it, I use
python setup.py sdist upload
The package is successfully added to PyPi package and I could install it using:
pip install py-quiz
The output of the installation:
Collecting py-quiz
Downloading py-quiz-0.1.1.tar.gz
Installing collected packages: py-quiz
Running setup.py install for py-quiz ... done
Successfully installed py-quiz-0.1.1
But then when i do,
user#somecomputer:~/PyQuiz$ py-quiz
py-quiz: command not found
How do I launch the game from command line? Please help me out here.
The application code is maintained here.
I finally solved the problem above by making the following changes.
There must be a package created in the directory and the folder structure should be as follows:
<Directory>
|-setup.py
|-dist
|-LICENCSE
|-readme
|-<package-name>
|-__init__.py
|-__main__.py
|-other files
and in the setup.py the following change should be
entry_points={
'console_scripts':['<command_name> = <package_name>.__main__:<function to be called>']
In my case, it is as follows:
entry_points={
'console_scripts':['py-quiz = py_quiz.__main__:main']
The main point is to create a package inside your project directory. This should solve major problems.
Related
This is an extension of SO setup.py ignores full path dependencies, instead looks for "best match" in pypi
I am trying to write setup.py to install a proprietary package from a .tar.gz file on an internal web site. Unfortunately for me the prop package name duplicates a public package in the public PyPI, so I need to force install of the proprietary package at a specific version. I'm building a docker image from a Debian-Buster base image, so pip, setuptools and tox are all freshly installed, the image brings python 3.8 and pip upgrades itself to version 21.2.4.
Solution 1 - dependency_links
I followed the instructions at the post linked above to put the prop package in install_requires and dependency_links. Here are the relevant lines from my setup.py:
install_requires=["requests", "proppkg==70.1.0"],
dependency_links=["https://site.mycompany.com/path/to/proppkg-70.1.0.tar.gz#egg=proppkg-70.1.0"]
Installation is successful in Debian-Buster if I run python3 setup.py install in my package directory. I see the proprietary package get downloaded and installed.
Installation fails if I run pip3 install . also tox (version 3.24.4) fails similarly. In both cases, pip shows a message "Looking in indexes" then fails with "ERROR: Could not find a version that satisfies the requirement".
Solution 2 - PEP 508
Studying SO answer pip ignores dependency_links in setup.py which states that dependency_links is deprecated, I started over, revised setup.py to have:
install_requires=[
"requests",
"proppkg # https://site.mycompany.com/path/to/proppkg-70.1.0.tar.gz#egg=proppkg-70.1.0"
],
Installation is successful in Debian-Buster if I run pip3 install . in my package directory. Pip shows a message "Looking in indexes" but still downloads and installs the proprietary package successfully.
Installation fails in Debian-Buster if I run python3 setup.py install in my package directory. I see these messages:
Searching for proppkg# https://site.mycompany.com/path/to/proppkg-70.1.0.tar.gz#egg=proppkg-70.1.0
..
Reading https://pypi.org/simple/proppkg/
..
error: Could not find suitable distribution for Requirement.parse(...).
Tox also fails in this scenario as it installs dependencies.
Really speculating now, it almost seems like there's an ordering issue. Tox invokes pip like this:
python -m pip install --exists-action w .tox/.tmp/package/1/te-0.3.5.zip
In that output I see "Collecting proppkg# https://site.mycompany.com/path/to/proppkg-70.1.0.tar.gz#egg=proppkg-70.1.0" as the first step. That install fails because it fails to import package requests. Then tox continues collecting other dependencies. Finally tox reports as its last step "Collecting requests" (and that succeeds). Do I have to worry about ordering of install steps?
I'm starting to think that maybe the proprietary package is broken. I verified that the prop package setup.py has requests in its install_requires entry. Not sure what else to check.
Workaround solution
My workaround is installing the proprietary package in the docker image as a separate step before I install my own package, just by running pip3 install https://site.mycompany.com/path/to/proppkg-70.1.0.tar.gz. The setup.py has the PEP508 URL in install_requires. Then pip and tox find the prop package in the pip cache, and work fine.
Please suggest what to try for the latest pip and tox, or if this is as good as it gets, thanks in advance.
Update - add setup.py
Here's a (slightly sanitized) version of my package's setup.py
from setuptools import setup, find_packages
def get_version():
"""
read version string
"""
version_globals = {}
with open("te/version.py") as fp:
exec(fp.read(), version_globals)
return version_globals['__version__']
setup(
name="te",
version=get_version(),
packages=find_packages(exclude=["tests.*", "tests"]),
author="My Name",
author_email="email#mycompany.com",
description="My Back-End Server",
entry_points={"console_scripts": [
"te-be=te.server:main"
]},
python_requires=">=3.7",
install_requires=["connexion[swagger-ui]",
"Flask",
"gevent",
"redis",
"requests",
"proppkg # https://site.mycompany.com/path/to/proppkg-70.1.0.tar.gz#egg=proppkg-70.1.0"
],
package_data={"te": ["openapi_te.yml"]},
include_package_data=True, # read MANIFEST.in
)
I'm building my first project on GitHub and my python src code uses an open-source, 3rd-party library that I have installed on my computer. However, I heard it is best practice to create a dep (dependencies) folder to store any additional libraries I would need. How do I actually install the libraries in the dep folder and use them from there instead of my main computer?
You have to create a requirements.txt file with each package on a separate line. e.g.
pandas==0.24.2
You also might want to add a setup.py to your python package. In the setup you have to use "install_requires" argument. Although install_requires will not install packages when installing your package but will let the user know which packages are needed. The user can refer to the requirements.txt to see the requirements.
You can check it here: https://packaging.python.org/discussions/install-requires-vs-requirements/
The following is an example of setup.py file:
from distutils.core import setup
from setuptools import find_packages
setup(
name='foobar',
version='0.0',
packages=find_packages(),
url='',
license='',
author='foo bar',
author_email='foobar#gmail.com',
description='A package for ...'
install_requires=['A','B']
)
Never heard about installing additional libraries in a dependencies folder.
Create a setup python file in your root folder if you don't already have it, in there you can define what packages (libraries as you call them) your project needs. This is a simple setup file for example:
from setuptools import setup, find_packages
setup(
name = "yourpackage",
version = "1.2.0",
description = "Simple description",
packages = find_packages(),
install_requires = ['matplotlib'] # Example of external package
)
When installing a package that has this setup file it automatically also install every requirement in your VENV. And if you're using pycharm then it also warns you if there's a requirement that's not installed.
I'm building a new PyPI package based on an existing open source project using setuptools and add some code modifications (they are not the same).
Example:
opensource-custom=2.13.1
Since this project requires dependencies that will look for opensource
what options can I pass to my setup.py when building my wheel files so when I do pip freeze/pip list I can see both?
opensource-custom=2.13.1
opensource=2.13.0
An example of this scenario is intel-numpy if you do a pip install of it, it will generate a copy of numpy.
>pip install intel-numpy
>pip freeze
icc-rt==2019.0
intel-numpy==1.15.1
intel-openmp==2019.0
mkl==2019.0
mkl-fft==1.0.6
mkl-random==1.0.1.1
numpy==1.15.1
tbb==2019.0
tbb4py==2019.0
It sounds like you want to make opensource a dependency of opensource-custom. To do this, you can specify the install_requires parameter in setup.py:
from setuptools import setup
setup(
name='opensource-custom',
install_requires=[
'opensource',
],
...
)
See https://packaging.python.org/guides/distributing-packages-using-setuptools/#install-requires
I am using the opencv-python project here. What I would like to do is recreate the wheel file again. So what I did was something like:
python setup.py bdist_wheel
This creates a dist directory and adds the wheel file there which I then take and try to install in an Anaconda environment as follows:
pip install ~/opencv_python-3.4.2+5b36c37-cp36-cp36m-linux_x86_64.whl
This is fine and seems to install fine. But when I try to use it and do
import cv2
I get the error:
ImportError: libwebp.so.5: cannot open shared object file: No such file or directory
I thought that creating the wheel file would take care of all the dependencies but I wonder if I have to do something else before the wheel generation to make sure everything is packaged correctly?
EDIT
I compare the wheel archives from the official sources and the one I generated and I see that the third party libraries are not included. So, my zip file contents are:
['cv2/LICENSE-3RD-PARTY.txt',
'cv2/LICENSE.txt', 'cv2/__init__.py',
'cv2/cv2.cpython-36m-x86_64-linux-gnu.so']
I have omitted some XML files which are not relevant. Meanwhile, the official archive has:
['cv2/__init__.py',
'cv2/cv2.cpython-36m-i386-linux-gnu.so',
'cv2/.libs/libswresample-08248319.so.3.2.100',
'cv2/.libs/libavformat-d485f70f.so.58.17.101',
'cv2/.libs/libvpx-1b5256ac.so.5.0.0',
'cv2/.libs/libz-83853723.so.1.2.3',
'cv2/.libs/libQtGui-55070e59.so.4.8.7',
'cv2/.libs/libavcodec-3b67922d.so.58.21.104',
'cv2/.libs/libswscale-3bf29a6c.so.5.2.100',
'cv2/.libs/libQtTest-0cf8861e.so.4.8.7',
'cv2/.libs/libQtCore-ccf6d197.so.4.8.7',
'cv2/.libs/libavutil-403a4871.so.56.18.102']
I have a python package ready for distribution on PyPI. To do this I am using twine as recommended on the in the Python docs. I have my setup.py file and this previously worked using the setup.py register upload command for my previous release.
To upload on to PyPi I am using:
python setup.py sdist
python setup.py bdist_wheel
twine upload dist\PyCoTools-2.1.2-py2-none-any.whl #this was created in the previous line
Now, on another computer I try using:
pip install PyCoTools
and it installs but then:
>>> import PyCoTools
Gives an import error. I go to the Libs/site-packages and all I see is this:
i.e. no folder called PyCoTools, just the dist info.
and inside that I just have
Which (obviously) doesn't incude the files that are in my package. Could anybody give me some pointers as to what I'm doing wrong?
Thanks
did you forget to put init.py inside your pyCoTools directory ? I had the same issue and I resolved it by adding this file.