Creating a setup.py - python

I have been working on a simple GUI tool for PIP and have a working prototype. I'm facing issues with creating a setup for it. The program is intended for Debian users (for now) and hence it'd like that after the installation a 'pip-gui' command from the terminal starts it for the user.
The link for the repository with the code is:
https://github.com/ayushpriya10/PIP-GUI
My attempt at making a setup can be found at:
https://github.com/GDGVIT/pip-gui
(The setup I created worked but then it didn't when I tampered a bit with it and hence I would prefer to make a fresh one instead of editing the existing one. I would like to make the necessary changes for the new setup on my personal repository and hence please let me know if I should make any changes to the structure of the repository.)
The code that I have currently is:
import os
import re
import codecs
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))
def find_version(*file_paths):
try:
f = codecs.open(os.path.join(here, *file_paths), "r", "latin1")
version_file = f.read()
f.close()
except:
raise RuntimeError("Unable to find version string.")
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
version_file, re.M)
if version_match:
return version_match.group(1)
raise RuntimeError("Unable to find version string.")
try:
f = codecs.open("README.rst", encoding="utf-8")
long_description = f.read()
f.close()
except:
long_description = ""
setup(
name="pip-gui",
version=find_version("pip_gui/mainGUI.py"),
description="",
url="https://github.com/GDGVIT/pip-gui",
author="GDGVIT",
packages=find_packages(include=[
"pip_gui",
"pip_gui.*"
]),
include_package_data=True,
# py_modules=["pip_gui.mainGUI"],
entry_points={
"console_scripts": [
"pip-gui=pip_gui.mainGUI:main"
]
},
classifiers=[
"Development Status :: 4 - Beta",
"License :: OSI Approved :: Apache Software License",
"Environment :: X11 Applications :: Qt",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2 :: Only",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: Implementation :: CPython"
],
install_requires=[
"beautifulsoup4>=4.5, <4.5.4"
]
)
The installation via 'pip install pip-gui' runs without any errors but the command 'pip-gui' in terminal shows the error 'command not found'.
Some changes that I want to make is changing the author to 'Ayush Priya ' and the URL pointing to my personal repository.

If a hyphen is appended to the package name (with no intervening space), the identified package will be removed if it is installed. This is just console formatting, so try removing the hyphen from pip-gui (make it pipgui).
Once that is done, if the program is in the directory your console is in, you should be able to just type the package name. Alternatively, use the full path - ie /path/to/program or cd to the directory and run ./program_name

Related

Problems with pip und Command line

I am trying to create a Python pip package. This works also well. I can successfully upload and download the package and use it in the Python code. What I can't do is to use the Python package via the command line. In another StackOverflow post I found the link to a tutorial. I tried to follow it. Obviously I made a mistake. Can you guys help me please ?
Installation of the package via pip
here you can see that the installation worked. Unfortunately, not the whole script fit on the image.
Pip does not find the package.
Unfortunately, I can't embed the images directly, so I'll just embed them as links.
I have created a simple Python package. It represents here only an example. Here you can see the structure of the folder
Riffecs
| .gitignore
| .pylintrc
| LICENSE
| README.md
| requirements.txt
| setup.py
|
|
\---riffecs
__init__.py
__main__.py
Here are the basic files shown.
main.py
from . import hello_world
if __name__ == '__main__':
hello_world()
and init.py
def hello_world():
print("Hello world")
In the following you can see the "setup.py". I am of the opinion that I have followed the instructions. But obviously I made a mistake somewhere. Can you please help me to correct this mistake.
import io
import os
import setuptools
def read_description():
url = "README.md"
""" Read and Return the description """
return io.open(os.path.join(os.path.dirname(__file__), url), encoding="utf-8").read()
def def_requirements():
""" Check PIP Requirements """
with open('requirements.txt', encoding='utf-8') as file_content:
pip_lines = file_content.read().splitlines()
return pip_lines
setuptools.setup(
name="riffecs",
version='0.0.3',
description='test',
entry_points={'console_scripts': ['hello-world=riffecs:hello_world',]},
long_description=read_description(),
long_description_content_type="text/markdown",
license="MIT",
keywords="test - riffecs",
url="https://github.com/Riffecs/riffecs",
packages=["riffecs"],
install_requires=def_requirements(),
python_requires=">=3.6",
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
],
)
In your setup.py file you have this line...
entry_points={'console_scripts': ['hello-world=riffecs:hello_world',]},
This is the entry point to calling you package via command line. This configuration is asking the entry point to be hello-world, which I tried and it runs fine.
In your image however you run riffecx which is not configured as an entrypoint to the package.
If you wanted the entrypoint to be riffecx. change the line to:
entry_points={'console_scripts': ['riffecx=riffecs:hello_world']},
Hope this helped.

Python module not found after build/install

I have an internal tool that we are using at work to pull some data and generate a report. The tool was written in python. I made some changes to the tool, and decided to tidy up the folder structure which seemed a bit messy to me. I probably broke something, but I'm determined to fix it and figure out what the issue is.
The project is named ReportCardLite, and my folder structure is like this:
ReportCardLite root folder
-Folder 1
-Folder 2
-rclite
-----__init.py__
-----A.py
-----B.py
-----C.py
-setup.py
-setup.cfg
-__init__.py
Originally, the author was importing by using the package name, which was odd to me since all the script files were in the same directory. So, in A.py for example, he would say something like "from rclite.B import fun".
I decided to remove the "unnecessary" module name from before all the import statements. Of course, that broke it, but I quickly figured out that I could add a line in my settings.json file to look within the rclite folder for all modules. Now my scripts were importing from one another without the module name, and running fine from within the IDE terminal window.
I next needed to build an executable from this module. The original author had included a setup.py and a setup.cfg file, so I used that to build and install this. But when I run this new executable, I receive errors that modules cannot be found. If I change it back to how it originally was, namely the "rclite.A" qualifier, it runs fine. I've spent hours trying to understand what is going on here, and I'm just out of ideas and cannot find any relevant questions using Google.
Can someone kindly point out which configuration I need to change in order to not have to put "rclite" in front of the import statements? Thanks!
Here is the setup.py script.. didn't see anything that looked promising.
"""ReportCardLite Packaging
See:
https://code.amazon.com/packages/ReportCardLite/trees/mainline
"""
# Always prefer setuptools over distutils
from codecs import open
from os import path
from setuptools import setup, find_packages
from cx_Freeze import setup, Executable
here = path.abspath(path.dirname(__file__))
import sys
# Get the long description from the README file
with open(path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = f.read()
setup(name='ReportCardLite',
# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/single_source_version.html
version='0.9.0',
description='RC.Lite for SIM',
long_description=long_description,
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
# How mature is this project? Common values are
# 3 - Alpha
# 4 - Beta
# 5 - Production/Stable
'Development Status :: 3 - Alpha',
# Indicate who your project is intended for
# 'Intended Audience :: Developers',
# 'Topic :: Software Development :: Build Tools',
# Pick your license as you wish (should match "license" above)
# 'License :: OSI Approved :: MIT License',
# Specify the Python versions you support here. In particular, ensure
# that you indicate whether you support Python 2, Python 3 or both.
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6'
],
# You can just specify the packages manually here if your project is
# simple. Or you can use find_packages().
packages=find_packages(exclude=['test']),
#packages = ['rclite'],
# Alternatively, if you want to distribute just a my_module.py, uncomment
# this:
# py_modules=["my_module"],
# List run-time dependencies here. These will be installed by pip when
# your project is installed. For an analysis of "install_requires" vs pip's
# requirements files see:
# https://packaging.python.org/en/latest/requirements.html
install_requires=[
'isoweek',
'jinja2',
'jsonpickle',
'jsonplus',
'markdown',
'pkg-resources',
'premailer',
'python-dateutil',
'pyxdg',
'six'
],
options={
'build_exe': {
'packages': ['lxml', 'asyncio', 'markdown.extensions'],
'include_files': ['templates/', 'webapp/']
},
},
# executables = [Executable("rclite/aiohttp_app.py", base="Win32GUI")],
executables=[Executable(script="rclite/aiohttp_app.py", targetName="run_rclite.exe")],
# List additional groups of dependencies here (e.g. development
# dependencies). You can install these using the following syntax,
# for example:
# $ pip install -e .[dev,test]
extras_require={
'dev': ['wheel'],
'test': ['mock'],
},
# If there are data files included in your packages that need to be
# installed, specify them here. If using Python 2.6 or less, then these
# have to be included in MANIFEST.in as well.
package_data={
# 'sample': ['package_data.dat'],
},
# Although 'package_data' is the preferred approach, in some case you may
# need to place data files outside of your packages. See:
# http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa
# In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
# data_files=[('my_data', ['data/data_file'])],
# To provide executable scripts, use entry points in preference to the
# "scripts" keyword. Entry points provide cross-platform support and allow
# pip to create the appropriate form of executable for the target platform.
entry_points={
'console_scripts': [
'rclite = rclite.__main__:main',
'rclite-gui = rclite.aiohttp_app.__main__'
],
},
)

How to package my python program so the user can install it using setup.py

I have a single python file right now and I am asked to convert it into a python module where the user can install it using python setup.py install. I am not sure how to do that. I have followed some instructions online and created the setup.py file and the init.py file. The setup.py file looks like this:
import setuptools
with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name="",
version="0.0.1",
author="",
author_email="",
description="",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/pypa/sampleproject",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
)
I am not sure if this setup.py file is correct.Also I don't know what I am supposed to do next. Can anyone help me and tell me what am I supposed to do? Is there tutorial that teaches this? I can't really find anything related. Also is my setup.py correct? Thanks!
There are several ways to do packaging. packaging Python Projects on python.org and setuptools docs are a good start.
Unfortunately, examples tend to focus on package distributions, not single modules. Instead of packages, use the py_modules keyword. Assuming your module is called "test.py", this setup.py will work
import setuptools
with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name="test",
version="0.0.1",
author="",
author_email="",
description="",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/pypa/sampleproject",
py_modules = ["test"],
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
)
If you think this will expand to multiple modules, then you can go back to using
setuptools.find_packages(). In this case, you want a subdirectory named after your desired package and put the init in there
some_random_project_file
+-- setup.py
README.md
LICENCE
+-- test
+-- __init__.py
test.py

pip package with OS specififc dependency

I want to create a pip package which dependent on some OS specific files:
Let's say there are:
dependency_Windows_x86_64.zip
dependency_Linux_x86_64.zip
dependency_MAC_OS_X.zip
I do not want to include all three archives in a package project, but download them dynamically during the pip install my-package based on user's OS. How can I do that ? Where should I put the code responsible for downloading/unzipping those files ?
My setup.py looks like this:
from setuptools import setup
setup(
name='my-package',
version='0.0.1',
description='Package description',
py_modules=['my_package'],
package_dir={'': 'src'},
classifiers=[
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: POSIX :: Linux',
'Operating System :: Microsoft :: Windows',
'Operating System :: MacOS',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.7'
],
python_requires='>=3.7'
)
The platform specific dependencies could be kept in separate Python projects (wrappers around data only packages) and then required from the main project like the following:
# setup.cfg
# ...
[options]
install_requires =
my_package_win_amd64 ; platform_system=="Windows" and platform_machine=="x86_64"
my_package_linux-x86_64 ; platform_system=="Linux" and platform_machine=="x86_64"
This approach doesn't depend on setuptools and could be used with other build systems.
First answer is give up and use setuptools. Look at Platform specific dependencies for a good write up of what to do.
Second answer is to make separate packages such as 'mylib-mac', 'mylib-win', 'mylib-linux'.
Third answer is to use the "console_script" approach. This will break. While it generates .exe files on Windows, it has odd failure modes. Also, some users will not be able to dynamically download files because they work from an internal clone of a repository. Randomly running code from the Internet on production can scare people.
Hope this helps!
A solution could be to publish platform specific Python wheels of your project. The platform specific files could be added to the pre-built distributions via a custom setuptools command (probably a sub-command of build, or maybe install).
This is not a full solution, but something like this might be a good start:
#!/usr/bin/env python3
import distutils.command.build
import setuptools
class build_something(setuptools.Command):
user_options = [
('plat-name=', 'p', "platform name to build for"),
]
def initialize_options(self):
self.plat_name = None
def finalize_options(self):
self.set_undefined_options('bdist_wheel', ('plat_name', 'plat_name'))
def run(self):
print(" *** plat_name: {} ***".format(self.plat_name))
print(" *** download the platform specific bits to 'build' ***")
class build(distutils.command.build.build):
sub_commands = [(
'build_something',
None,
)] + distutils.command.build.build.sub_commands
setuptools.setup(
cmdclass={
'build_something': build_something,
'build': build,
},
# ...
)
And then the Python wheels could be built like this:
$ ./setup.py bdist_wheel -p win_amd64

Custom package installed but not found in another project

I created a Python folder/project and published the code on Github. The folder has the following structure:
/modulename/__init__.py
/modulename/setup.py
/modulename/somefunctions.py
/modulename/README.md
The name of my package is module_helloworld and setup.py looks as follows:
import setuptools
with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name="module_helloworld",
version="0.0.1",
author="Hello World",
author_email="hello#world.com",
description="Hello world module",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://www.website.com",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
)
In another project, I installed it in Pycharm using the command
pip install git+https://github.com/Username/module-helloworld.git
That worked fine and in my Project Settings I see the package installed (noticed that it was installed with the name module-helloworld however) .
Now when I open the python console (or a new Python file) and I type
import module_helloworld
Then I get the error:
ModuleNotFoundError: No module named 'module_helloworld'
What did I do wrong?
In my case I had to restructure the folder structure as follows:
root/module_helloworld/__init__.py
root/module_helloworld/somefunctions.py
root/setup.py
And then in the other project I could call it in the normal way.
Inside the function __init__.py to import the functions I had to change it to the following:
# import somefunctions changed to:
from module_helloworld import somefunctions

Categories

Resources