Learn to Code via Tutorials on Repl.it!

← Back to all posts
How to create python packages and upload to pypi
ChezCoder (1497)

Packaging to PyPi in Python

Hello repl community! Wan't to create a package like termcolor, or my very very newly released package? Don't worry! This tutorial will take you through all of the processes!

In this tutorial, we will be creating a package named "example_package". Be sure to replace it with your package's name unless you want it to be called "example_package"

Step 1

Step one, ok. Before we start, you will need a few things.

  • An account on PyPi (Email verified)
  • An account on TestPyPi (Email verified)
  • Python 2.7 and up & Pip (Python 3 is recommended)
  • Github (optional)

So after you have prepared these things, let's move onto step 2!

Step 2

Ok, so first thing's first, we need to get a "token". This token is basically a number representing your pypi account. Go to https://pypi.org/manage/account/ and scroll down to API Tokens. Click the "add api token" button. You can use another if you already created one before. Don't tell anyone your api token as it is a secret! I recommend you put it in a .env file.

Step 3

Make sure you have terminal/command line open. If you are doing this in repl, use this shortcut:
Windows: ctrl + shift + s
Linux/Max: cmd + shift + s

After opening your console you need to install a few packages. Type in the following:
pip install wheel
pip install twine
pip install setuptools

These commands install the required wheel, twine, and setuptools.

Step 4

Now that you have setup your required tools, go to your python repository and do the following:

  • Create a folder and name it your package's name. In this case, "example_package". This folder is where all the code for your package will be but the "main.py" file is called __init__.py.
  • Now create a README.md and a LICENSE file. If you need help with markdown for your readme, check out this tutorial. If you are using the MIT license (which I will be using), you can copy it below. Or else, you can check out https://choosealicense.com/ to generate a license.
MIT License

Copyright (c) YEAR FULLNAME/USERNAME

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.
  • Then, create a tests folder. This is a placeholder file, meaning that it is used to reserve space for something. This will be kept untouched by us.
  • Lastly, create a file named setup.py. This is the configuration or the "settings" for your package. Paste the code below and change the options to suit your liking.
import setuptools

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

setuptools.setup(
    name="package-name",
    version="0.0.1",
    author="your name",
    author_email="your email",
    description="a short description.",
    long_description=long_description, # don't touch this, this is your README.md
    long_description_content_type="text/markdown",
    url="The link to the github/repl/repository",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
)

Your file tree should look like the picture below:

Step 5

Now that you are done creating all your files, we can start the installation. First we need to specify where to create the files. Enter this command: cd REPOSITORY FILE NAME. If you are doing this on repl, you can enter the name of your repl in the repository name. To create a new release (in this case, it should be in 0.0.1 or 0.1.0 or 1.0.0 etc) enter this in the console: python3 setup.py sdist bdist_wheel. This script should write a few files and folders. You can look at them but do not edit anything. Your file tree should look like the pictures below:

Step 6

Time to upload the files to pipy! To start, you need make sure you want to use the name you are currently using. Pypi doesn't allow you to delete a file/package and create another package with the same name. If you aren't sure, it is recommended to test it with https://test.pypi.org/, which deletes your package after 24 hours (you will need an api token from testpypi). If you want to upload to test pypi, use this command: python3 -m twine upload --repository testpypi dist/*. If you want to upload to the real pypi, use this command: python3 -m twine upload --repository pypi dist/*.
After a bunch of text output, it will prompt for your username. Enter this: __token__. This tells pypi that you don't have a username but rather a token. Enter the words __token__ literally. Don't put your token in the words token. Your shell should look similar to the below:

Step 7

Now that you have entered your username, it should prompt you for the password. Remember the API-Token I mentioned before? Entire this into the password. Make sure that the password started with "pipy-". If it did't, add it before pasting it in the password box. The input box is echo-free meaning that you can't see what you typed so makesure that you have the correct password pasted. If it was successfull, then it should give you a link to your project. Congrats! You have successfully created a package in python. If there was an error, here are the likely culprits:

  • You entered the incorrect username and/or password - Retry the command and re-enter the username and password. Make sure you copied the correct API-token.
  • The name you chose for your package already existed - Try changing the name of the package by changing the file name in the file tree and changing the information in setup.py. Delete the dist folder and the .egg folder, then re-run both commands:
  • python3 setup.py sdist bdist_wheel
  • python3 -m twine upload --repository pypi dist/*

Step 8

If everything has gone successfully, your console should look like this (I uploaded to testpipy):
(I canceled the upload)

Done!

Congrats! You have successfully uploaded a project to pypi. To release a new version, just change the version in setup.py and re-run these two commands:

  • python3 setup.py sdist bdist_wheel
  • python3 -m twine upload --repository pypi dist/*
    If you want to automate this process, you can use this script I have created:
def setup():
    import os

    print("installing modules...")
    cmds = [
        "pip install setuptools",
        "pip install twine",
        "pip install wheel",
        "python3 setup.py sdist bdist_wheel",
    ]
    for i in cmds:
        os.system(i)

    print("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nLogin:")
    os.system("python3 -m twine upload --repository pypi dist/*")
    # you will have to maually enter your username and password.

input("[ENTER]")
setup()

Conclusion

Thank you for reading all the way to the end! If you have any questions, just comment below and I will try my best to reply!
Also, please upvote. This post took me two whole days to complete :D

Commentshotnewtop
Wumi4 (91)

Hello @ChezCoder!When I do the command create release on step 5,It says it can't open the file setup.py because no such file or directory,help me pls :(

ChezCoder (1497)

@DangHoang2 oh, thats because it already cd'd for you!

ChezCoder (1497)

@DangHoang2 also, the tests folder is supposed to be empty! You should mode the files from test/ out

Warhawk947 (518)

This is really helpful, thanks!

Codemonkey51 (850)

Your module is 404'ing :(

ChezCoder (1497)

@Codemonkey51 this is because I don't want people uploading this package.

Jakman (450)

Thanks for the info. I have a complete file comprehension package for malicious code usage.