3 horizontal lines, burger
3 horizontal lines, burger
3 horizontal lines, burger
3 horizontal lines, burger

3 horizontal lines, burger
Remove all
LOADING ...

Content



    Publishing Your Python Package on PyPI

    Clock
    22.10.2025
    /
    Clock
    22.10.2025
    /
    Clock
    8 minutes
    An eye
    149
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0

    What is this article about, and why does it exist?

    I'm writing this article for those who are just starting out or want to publish their package on PyPI. When I first tried publishing a PyPI package myself using the official guide, I had a lot of questions about why and how.
    I'm not saying the article is bad—it's excellent and comprehensive. Definitely read it.
    Furthermore, I felt this article was a bit overwhelming for a beginner, and it would be a good idea to split it into two parts:
    1. A quick start with the bare minimum.
    2. For those who are more familiar with the topic, there will be a comprehensive and in-depth guide. (Under development)
    I'd also like to point out that I'll be writing about a new (modern) approach to publishing packages, namely, using the pyproject.toml configuration file, which contains all the necessary configurations for packaging your code.

    Introduction

    Why bother with packaging, who needs it, and what exactly is PyPI? Let’s start at the beginning.
    PyPI, the Python Package Index, is a repository of specially packaged Python projects—these can be scripts, libraries, full frameworks, or applications. Anyone can download these packages using tools like pip.
    A PyPI package is essentially a format for distributing Python source code. Today, packages are created using the pyproject.toml configuration file, which replaced the earlier setup.py script and setup.cfg files.
    For simplicity, I’ll use the term "package" to mean a PyPI package (or Python package) throughout this explanation. It will make things easier for both of us.
    This packaging standard is relatively new. It came into widespread use around 2016 with the introduction of PEP 518, which established a unified way to publish and package Python projects via pyproject.toml.
    Who needs this system? Mainly developers, testers, and anyone working with Python. Packaging standardizes the way Python projects are distributed and deployed on PyPI, making life easier for everyone involved.
    But why do we need PyPI at all? Why not just use platforms like GitHub or Bitbucket to store source code? The answer depends on perspective. Python differs significantly from languages like C++ or JavaScript. For example, C++ lacks an official package index like PyPI, while JavaScript uses the Node Package Manager (NPM).
    Each language ecosystem follows different norms and levels of complexity. If you want to quickly and easily install functionality with a single command, you need a central hub with specific rules and standards for package structure and operation. That’s exactly what PyPI provides.
    For instance, if you want to build web applications or an entire website, you just install Django from PyPI—and you’re ready to go.

    pip install django
    An example how to install a package from PyPI
    Or if you want to add support for the HTMx library to your templates (html pages), simply install the corresponding node module:
    npm i htmx
    An example how to install a package from NPM

    Setting Up the Basics

    To create your own package for PyPI, you need to have Python and pip installed. Additionally, it’s recommended to create virtual environments both for the package you’re developing and for any projects where you plan to use that package.
    Pip, which stands for Package Installer for Python, is a command-line tool that enables you to download packages directly from the PyPI index.
    Here are the steps to get started:
    1. Install Python from the official website: https://www.python.org/downloads/. Pip will be installed automatically along with Python.
    2. Create a directory and a virtual environment where you will develop your package. For example, call this directory UsefulPackage.
    3. Register an account on pypi.org. If you’re new to packaging, it’s also a good idea to register on test.pypi.org, a test PyPI server.
    Why should you bother registering on test.pypi.org instead of publishing directly to pypi.org? It’s more a matter of etiquette. While you can publish immediately on the main PyPI, using the test server helps prevent cluttering the public index with test or incomplete packages. The test index lets you safely practice publishing and working through the details of package development.
    If you’re unfamiliar with virtual environments, here’s how you create one:
    python -m venv .venv
    1. python specifies the Python version you want to use to create the environment.
    2. -m venv tells Python to use the virtual environment module.
    3. .venv is the directory where the virtual environment will be saved.
    That's all we need for what follows. So, at this point, our package structure is as follows:
    1. UsefulPackage
    2. .venv

    Additionally, a test project

    You can also create a test project where we'll install the newly created package, just to make sure we've done everything correctly and the package actually works as expected. To do this, create a UsefulProgram directory. Then, create a virtual environment there, as described above.
    We'll also need a main.py file, which we'll run through the interpreter.
    Create it and paste the following test code:
    from useful_package_YOURNAME.main import isWork if __name__ == "__main__": isWork()
    Instead of YOURNAME, you'll need to substitute your own name or any other string. This is necessary so that everyone can create their own package and avoid conflicts of interest. Alternatively, you can come up with your own package name and use that.
    That's all we need for now. So, at this point, our project structure is as follows:
    1. UsefulProgram
    2. .venv
    3. main.py
    If you run it now, you'll get an error about invalid package imports; the package doesn't exist yet.

    A Quick Start to Creating a Basic Python Package for PyPI

    This chapter will guide you through the basic steps to publishing your first package on PyPI. I'll also cover all the nuances and specifics of our actions as we create the package.

    Creating the Minimal Project Structure

    First, you'll need to create the appropriate structure for the package. It will look like this:
    1. UsefulPackage/
    2. .venv/
    3. useful_package_timthewebmaster/
    4. LICENSE <- License file, you can choose here
    5. pyproject.toml <- Let's talk about it later, configuration file
    6. dist/ <- The folder where source distribution and build distribution gonna be placed
    7. src/
    8. useful_package_timthewebmaster/ <- Source of your package
    9. __init__.py
    10. main.py
    PyPI Source Distribution - A package distribution format (usually created with the python -m build --sdist command) that provides the metadata and core source files needed for installation with a tool like pip or to create a complete package.
    PyPI Build Distribution - A package distribution format that contains files and metadata that can be installed simply by moving them to the desired location on the target system.
    In the src/useful_package_timthewebmaster our scripts will be located there, which we want to use in other projects.

    Configuring the pyproject.toml file

    After creating the package structure, we need to define the configuration file, pyproject.toml. This file has only four required parameters.
    In the [build-system] section, we specify the backend (and version) to use for building the package. And in the [project] section, we specify only two required fields: the package name and its version. All other fields are optional.
    [build-system] requires = ["hatchling >= 1.26"] build-backend = "hatchling.build" [project] name = "useful-package-timthewebmaster" version = "0.0.1" authors = [ { name="Tim The Webmaster", email="timachuduk@gmail.com" }, ] license = "MIT" license-files = ["LICEN[CS]E*"]
    Although the configuration file above is the bare minimum for creating a package, I highly recommend familiarizing yourself with the other configuration fields. Plus, all the possible classifiers will help you define your package's niche and find the right users accordingly.
    I usually start from this basic template, created by me and for myself, and simply change the different fields:
    [build-system] requires = ["hatchling >= 1.26"] build-backend = "hatchling.build" [project] name = "django-referer-breadcrumbs" version = "0.0.2" authors = [ { name="Tim The Webmaster", email="timachuduk@gmail.com" }, ] description = "A Django app for generating a breadcrumbs from the refferer url (previosly visited), or by using yourown list of urls. It is customizable via template variables. Easy to set up and configure" readme = "README.md" requires-python = ">=3.10" classifiers = [ "Development Status :: 3 - Alpha", "Programming Language :: Python :: 3", "Operating System :: OS Independent", "Environment :: Console", "Environment :: Plugins", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Natural Language :: English", "Natural Language :: Russian", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Content Management System", "Topic :: Internet :: WWW/HTTP :: WSGI", "Topic :: Software Development :: Pre-processors", ] license = "MIT" license-files = ["LICEN[CS]E*"] dependencies = [ "Django>=5.1.7", ] keywords = ["django", "django app", "breadcrumbs", "navigation", "referer", "customizable", "timthewebmaster"] [project.urls] "Homepage RU" = "https://timthewebmaster.com/ru/tools/breadcrumbs-for-django/" "Homepage EN" = "https://timthewebmaster.com/en/tools/breadcrumbs-for-django/" "Issues RU" = "https://timthewebmaster.com/ru/tools/breadcrumbs-for-django/#comments_limiter" "Issues EN" = "https://timthewebmaster.com/en/tools/breadcrumbs-for-django/#comments_limiter"
    Using as an example from one of my project

    Generating a Python Package

    We have everything we need to build our first package. But first, let's install the Python interpreter in the current virtual environment (please remember to create and activate it):
    pip install build
    Go to the directory with the Python package settings file, i.e. pyproject.toml, and start the package creation process:
    cd useful_package_timthewebmaster; python -m build
    And this is what the build module's output will look like. More specifically, two archives will be created: the source distribution and the build distribution:
    We'll now have the following archives: useful_package_timthewebmaster-0.0.1-py2.py3-none-any.whl and useful_package_timthewebmaster-0.0.1.tar.gz, which are now ready to be indexed by PyPI.

    Uploading the package to PyPI

    To upload them, you'll need to install another module, the twine module (don't forget to create and activate a virtual environment).
    pip install twine
    If you're still working with the test repository, to push a package to the test index, you need to specify it using the --repository flag with the testpypi argument. Finally, specify all the archives you want to push.
    python -m twine upload --repository testpypi ./dist/*
    In my case, I will send all the archives in the dist directory
    Well, if you no longer need to test the methods and ways of publishing your packages, then publishing a package to the open index looks like this:
    python -m twine upload ./dist/*
    At this stage, you'll be asked for an API token to confirm who wants to publish their package and where. You'll need to create one. There's a small caveat: each token has a scope, so to speak. You can specify a scope for all packages, or you can specify a scope for each one.
    Simply create one token for all packages and save it somewhere easy to find and use.
    To create a token for the test index, go here: https://test.pypi.org/manage/account/#api-tokens
    To create a token for the public index, go here: https://pypi.org/manage/account/#api-tokens
    This is what the result of successfully publishing a package to the PyPI index will look like (regardless of whether it's a test server or not):
    Congratulations, you've successfully published your first Python package, and now everyone can use it. Welcome to the community!

    A complete guide to creating Python packages for PyPI.

    In the process. Please wait.

    Checking if you've built a working package

    After successfully building and uploading the package to the PyPI index (or the test index), it's highly recommended to check whether your module works and imports at all. To do this, create a simple project, create and activate a virtual environment, and finally install the package:
    If the package was uploaded to the PyPI test index, then to install it, you need to:
    pip install --index-url https://test.pypi.org/simple/ useful-package-timthewebmaster
    Don't forget to replace useful-package-timthewebmaster with your package name.
    To update it, add the --upgrade flag.
    pip install --index-url https://test.pypi.org/simple/ useful-package-timthewebmaster --upgrade
    Don't forget to replace useful-package-timthewebmaster with your package name.
    If you already upload packages to public PyPI servers, install the packages as usual:
    pip install useful-package-timthewebmaster
    Don't forget to replace useful-package-timthewebmaster with your package name.
    Next, you just need to run the project that uses your package and test it. In our case, simply run the script from the terminal:

    Do not forget to share, like and leave a comment :)

    Comments

    (0)

    captcha
    Send
    LOADING ...
    It's empty now. Be the first (o゚v゚)ノ

    Other

    Similar articles


    Why and how to solve server response delay, err_http2_ping_failed error, my investigation and solution

    Clock
    29.09.2024
    /
    Clock
    02.10.2025
    An eye
    1259
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    In this article, I will describe in detail how I solved the problem of server response delays (err_http2_ping_failed) to client requests. I will describe the operation of the ERR_HTTP2_PING_FAILED error …

    How to make a simple python scraper + a ready-for-use example

    Clock
    10.12.2024
    /
    Clock
    02.10.2025
    An eye
    435
    Hearts
    1
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    In this article I will show how to make a simple python scraper. This parser is an example of how to parse static and dynamic sites. With the source code …

    How to Run Django Server: 4 Ways (runserver, Gunicorn, Nginx) | Complete Guide

    Clock
    17.10.2025
    /
    Clock
    17.10.2025
    An eye
    141
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    A complete guide on launching a Django server. Learn 4 essential methods: from the default runserver for development to using WSGI/ASGI, Gunicorn, and Nginx for a live (production) environment.