Publishing your first Python package on PyPI (Python Package Index) feels like sending your code off to collegeโitโs out there in the world, ready to make you proud (and maybe help someone too).
In my case, I was working on my own version of mkdocs-material.
Initially, I was all about the UIโjust trying to get it to look good and work as intended. After some effort, I had something usable and thought, "Alright, let's figure out the deployment."
The original mkdocs uses a Python package for its installer, so you can just pip install mkdocs
, mkdocs new .
, and then mkdocs build
to convert markdown files into HTML.
Itโs simple, elegant, and works like a charm.
I wanted the same experience for my projectโan easy pip install
setup to make deploying my version of mkdocs-material.
So, it was my time to learn how to build my own Python package and publish it. And thatโs exactly what weโll do here, step by step.
Donโt worryโitโs easier than debugging a Friday night code bug XD
Step 1: Structure ๐
A well-structured project is like a clean kitchenโyou can find your tools (or code) easily and avoid unnecessary messes.
Here's what our project layout will look like:
โโโ dev_to/
โ โโโ __init__.py
โ โโโ say_hello.py # Your module code
โโโ tests/
โ โโโ test_say_hello.py
โโโ README.md
โโโ setup.py # Package metadata
โโโ pyproject.toml # Build system config
โโโ LICENSE
Step 2: Code ๐
This is the heart of your packageโwhat it does and why it exists.
-
dev_to/say_hello.py
A simple function that greets users:
def say_hello(name):
return f"Hello dev.to, from {name}!"
-
dev_to/__init__.py
Makes your function accessible at the package level:
from .say_hello import say_hello
Step 3: Tests โ
Tests ensure your code behaves as expected and helps you avoid embarrassing bugs. Trust me, your future self will thank you.
-
tests/test_say_hello.py
A basic test script:
from dev_to import say_hello
def test_say_hello():
result = say_hello("World")
assert result == "Hello dev.to, from World!"
print("Test passed!")
if __name__ == "__main__":
test_say_hello()
$ p tests/test_say_hello.py
Test passed!
Step 4: Metadata
Metadata describes your package what it is, who made it, and how others can use it.
-
setup.py
Configure your package:
from setuptools import setup, find_packages
setup(
name="dev_to",
version="0.1.0",
author="lovestaco",
description="A simple example package",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/lovestaco/dev_to",
packages=find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires=">=3.6",
)
-
pyproject.toml
Declare the build system:
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
Step 5: Build the Package
Building generates the distributable files required for publishing.
Install the tools:
pip install build
Build your package:
python -m build
This creates a dist/
folder containing .tar.gz
and .whl
files.
$ python -m build
* Creating isolated environment: virtualenv+pip...
* Installing packages in isolated environment:
- setuptools
- wheel
.
.
.
adding 'dev_to-0.1.0.dist-info/RECORD'
removing build/bdist.linux-x86_64/wheel
Successfully built dev_to-0.1.0.tar.gz and dev_to-0.1.0-py3-none-any.whl
Step 6: Moment of Truth
Install the package locally:
pip install dist/dev_to-0.1.0-py3-none-any.whl
Try it out:
Step 7: Publish to PyPI ๐
Install Twine:
pip install twine
Upload your package:
python -m twine upload dist/*
You'll need your PyPI credentials. Once uploaded, your package is live! ๐
Install it like this:
pip install dev-to
Iโve been working on a super-convenient tool called LiveAPI.
LiveAPI helps you get all your backend APIs documented in a few minutes
With LiveAPI, you can quickly generate interactive API documentation that allows users to execute APIs directly from the browser.
If youโre tired of manually creating docs for your APIs, this tool might just make your life easier.
Top comments (0)