Hello everyone,
While designing our projects, we always constantly use the structures we plan to use. PyPI comes to the rescue when these structures are generally useful for us when we want to make a package of these structures instead of writing them over and over again…
First, let’s have a sample package to pack. Let’s say we have a structure that converts the given text to a list. We also want to package this structure. We are starting to create our project named “text_to_list”. When creating a library for PyPI, it is necessary to follow its standards;
textToListPackage/ ├── LICENSE ├── pyproject.toml ├── setup.py ├── README.md │── text_to_list/ │ ├── __init__.py │ └── text_to_list.py └── tests/
Let’s take a look at the file names in order;
LICENSE, as you can imagine, contains the details of your library’s license. It specifies details such as which packager the clients downloading your pyproject.toml library will install your package, who wrote it, and version dependencies. README.md is the visible documentation of the project in PyPI. Our package itself should have library files under text_to_list. The tests contains the tests of the library.
Preparing the Project for Packaging
In the standard README file of the project, we write how we can load and use our library using Markdown;
# How to Install
```shell
pip install text_to_list
```
# How to Use It
```python
from text_to_list import text_to_list
text_to_list("Sample Sentence for Library")
```
You can do a quick Google search for the LICENSE file, I prefer to using the LICENSE file from the official document;
Copyright (c) 2022 The Python Packaging Authority Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
After defining the structures such as classes and functions to be used in our library in text_to_list.py, we do not forget to call these files in init.py, so they will be accessible after the package is installed.
text_to_list.py;
def text_to_list(text: str):
"""
:param text: The text to be taken as a string and converted to a list.
:return: Return parameter of function converted to list
"""
listed_text = text.split(sep=" ")
return listed_text
__init__.py;
from .text_to_list import text_to_list
Our setup.py file is a summary of the project, we specify the version information, ownership and dependencies here. There are multiple alternatives to package your project (setuptools, Hatcling, Flit etc.), but since the most common one is setuptools, I wanted to explain it in the same structure;
import setuptools
with open('README.md', 'r', encoding='utf-8') as fh:
long_description = fh.read()
setuptools.setup(
name='text_to_list',
author='Sezer BOZKIR',
version="0.0.1",
author_email='admin@sezerbozkir.com',
description='Example PyPI (Python Package Index) Package',
keywords='example, pypi, package',
long_description=long_description,
long_description_content_type='text/markdown',
url='https://github.com/natgho/text_to_list',
project_urls={
'Documentation': 'https://github.com/natgho/text_to_list',
'Bug Reports':
'https://github.com/natgho/text_to_list/issues',
'Source Code': 'https://github.com/natgho/text_to_list',
},
package_dir={'': 'text_to_list'},
packages=setuptools.find_packages(where='text_to_list'),
classifiers=[
# see https://pypi.org/classifiers/
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'Topic :: Software Development :: Build Tools',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3 :: Only',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
],
python_requires='>=3.7',
install_requires=['requests'],
)
Here, I added the “requests” library as a dependency as an example of installing dependencies. When we install our package, the requests library will be automatically installed in this way.
If all is well, we can now install and test our package;
pip install .
When our library and dependencies are loaded, we should be able to open the interactive console and run it as follows;
from text_to_list import text_to_list
print(text_to_list("This is very funny sample."))
# output: ['this', 'is', 'very', 'funny', 'sample.']
Now we can install our package and move on to the pull step via pypi.
Testing Our Package in a Test PyPI Environment
Before we install the package in the real environment, we test it by registering and importing our package into PyPI’s test environment to make sure everything is working fine. (link)
To install our package on the PyPI environment, we need to install the Twine library. This library will help us install our package. (details);
pip install twine
We build our package;
python3 -m build
When this step is completed successfully, we should be able to see the “dist” folder under our project. The dist folder is the folder containing the details of our package. To transfer our project to the test environment;
python -m twine upload --repository testpypi dist/*
In the output of this command, console ask for your username and password, and enter the information you registered in this step;
Uploading distributions to https://test.pypi.org/legacy/ Enter your username: natgho Enter your password: Uploading text_to_list-0.0.1-py3-none-any.whl 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.4/7.4 kB • 00:00 • ? Uploading text_to_list-0.0.1.tar.gz 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.3/7.3 kB • 00:00 • ? View at: https://test.pypi.org/project/text-to-list/0.0.1/
When we enter the URL address, we see that our README file has been added as a description and everything is fine. Now it’s time to take our package to the real environment;
twine upload dist/*
We see the same steps, this time on the console for the real environment;
Uploading distributions to https://upload.pypi.org/legacy/ Enter your username: natgho Enter your password: Uploading text_to_list-0.0.1-py3-none-any.whl 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.4/7.4 kB • 00:00 • ? Uploading text_to_list-0.0.1.tar.gz 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.3/7.3 kB • 00:00 • ? View at: https://pypi.org/project/text-to-list/0.0.1/
Now that everything is completed, we try to install our package, this time by calling it via pip;
sezer@optimist ~> pip install text-to-list pip install text-to-list Collecting text-to-list Using cached text_to_list-0.0.1-py3-none-any.whl (2.3 kB) Collecting requests Using cached requests-2.28.1-py3-none-any.whl (62 kB) Collecting certifi>=2017.4.17 Using cached certifi-2022.9.24-py3-none-any.whl (161 kB) Collecting idna<4,>=2.5 Using cached idna-3.4-py3-none-any.whl (61 kB) Collecting charset-normalizer<3,>=2 Using cached charset_normalizer-2.1.1-py3-none-any.whl (39 kB) Collecting urllib3<1.27,>=1.21.1 Using cached urllib3-1.26.12-py2.py3-none-any.whl (140 kB) Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests, text-to-list Successfully installed certifi-2022.9.24 charset-normalizer-2.1.1 idna-3.4 requests-2.28.1 text-to-list-0.0.1 urllib3-1.26.12
https://github.com/Natgho/text-to-list
See you in another article, you can reach the project example from the Github link above 🙂
References;
https://packaging.python.org/en/latest/tutorials/packaging-projects/
https://github.com/psf/requests
https://github.com/tomchen/example_pypi_package
https://towardsdatascience.com/create-your-own-python-package-and-publish-it-into-pypi-9306a29bc116