The Ultimate Guide You Need To Publish Your Python Package In Just 9 Easy Steps
Tags: python, beginners, tutorial
Published: 2021-12-26 18:18:34

### Directory structure  
- Create a directory that is named exactly how you want your package to be named.  
- Place all the files, folders and classes that you want to publish into this directory.
- Create files required by PyPI to prepare the project for distribution. 
- It should look something like this: 

![directory structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z75fm28j1oeomkys96dl.png)

### Clean your code  
- Remove all "print" statements from the code.  
- Use logs instead of print statements(debug/info/warn etc..)  

### Configuring metadata  
- `setup.cfg` --> It is the configuration file for **setuptools**. It tells setuptools about your package(such as the name and version) as well as which code files to include. There are a variety of [metadata and options supported](https://setuptools.pypa.io/en/latest/userguide/declarative_config.html) here.

```
[metadata]
description-file = README.md  
```   

- `setup.py` -->  It is the build script for which tells setuptools about your package(such as the name and version) as well as which code files to include.   

> setuptools is a library designed to facilitate packaging Python projects.  

  Open `setup.py` and enter the following content. Change the name to include your username; this ensures that you have a unique package name and that your package doesn’t conflict with packages uploaded by other people.

```py
from setuptools import setup, find_packages

version = '0.0.1' # Any format you want

with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()

setup(
  name='your-package-name',
  packages=find_packages(),
  version=version,
  license='MIT',
  description='Short description',
  long_description=long_description,
  long_description_content_type="text/markdown",
  author='Author Name',
  author_email='author@email.com',
  url='https://gitlab.com/username/repo-name',
  download_url=f'https://gitlab.com/username/repo-name/-/archive/{version}/repo-name-{version}.tar.gz',
  keywords=['Some', 'keywords'],
  install_requires=[
          'dependency-1',  # All external pip packages you are importing
          'dependency-2',
      ],
  classifiers=[
    'Development Status :: 3 - Alpha',
    'Intended Audience :: Developers',
    'Operating System :: OS Independent',
    'Topic :: Software Development :: Build Tools',
    'License :: OSI Approved :: MIT License',
    'Programming Language :: Python :: 3.7',
    'Programming Language :: Python :: 3.8',
  ],
)  
```
  You can find details about each arguments [here](https://packaging.python.org/tutorials/packaging-projects/#configuring-metadata).  

### Creating README.md (optional but recommended)  
Open README.md and enter details about your package. You can customize this as you’d like. This content can be displayed on the homepage of your package on PyPI.  

### Creating a LICENSE  
It’s important for every package uploaded to the Python Package Index to include a license. This tells users who install your package the terms under which they can use your package. For help picking a license, see [https://choosealicense.com/](https://choosealicense.com/). Once you have chosen a license, open LICENSE and enter the license text. For example, if you had chosen the MIT license:
```
Copyright (c) 2021 YOUR NAME
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.
```  

### Create a PyPI account  
Register yourself for a PyPI account [here](https://pypi.org/account/register/). Remember your username (not the Name, not the E-Mail Address) and your password, you will need it later for the upload process.  

### Upload your package to github/gitlab  
Create a github/gitlab repo including all the above files and folders. Name the repo exactly as the package.  
If uploading package to Gitlab, 
  - After uploading the required files, go to `Repository --> Tags --> New Tag` and create new tag(tag name should be same as the version) for every release of the package to PyPI. 
 
![Creating Tags](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uuekaftfa9a0btd5ff4j.png)  
  
  - This copied link should be the same as *download_url* argument in the `setup.py` file.   

If uploading package to GitHub, 
 - After uploading the required files, follow steps mentioned [here](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository) to create a release.  

> **NOTE:  
Every time you want to update your package later on, upload a new version to gitlab/github, create a new release as discussed, specify a new release tag and copy-paste the link to Source into the setup.py file (do not forget to also increment the version number).** 

### Uploading the distribution archives  
The first thing to do is register an account on TestPyPI, which is a separate instance of the package index intended for testing and experimentation. To register an account, go to [here](https://test.pypi.org/account/register/) and complete the steps on that page. You will also need to verify your email address before you’re able to upload any packages.  

After registration, use **twine** to upload the distribution packages.  
- Navigate to folder where you have al the files and package located.  
- Run `python setup.py sdist`
- Install Twine:  `pip install twine`
- Run twine: `twine upload --repository testpypi dist/*`
Upload successful    
  
### Installing newly uploaded package 
- `pip install -i https://test.pypi.org/simple/ your-package-name`

When you are ready to publish your package to **PyPI** after proper testing, run the following command:  
`twine upload dist/*`  
to publish it on PyPI.    

**NOTE**:    
Now for every future updates to your package:  
- change the version number in setup.py file
- create tag/release in gitlab/github
- update the *download_url* in setup.py
- Run `python setup.py sdist`
- Run `twine upload dist/*`
- Run `pip install your-package --upgrade` --> to see whether your changes worked.  

AND IT'S DONE ...YAAAY !!    
Visit PyPI and search for your package name. Now you can use your package just like any other python packages by installing it with pip i.e. `pip install your-package-name`.  

I hope this blog helped you understand how to publish your own Python Package easily.

Happy coding !!