DEV Community

Cover image for How to Bake A Python Package Cake🐍+📦=🎂
sirfuzzalot
sirfuzzalot

Posted on • Updated on

How to Bake A Python Package Cake🐍+📦=🎂

Let's bake a package cake 🎂! You will need...

Ingredients

Item Location Description
library or application ./src/[name of library or application]/[your code] Your code that does something useful or fun
pyproject.toml ./pyproject.toml Build configuration information
setup.cfg ./setup.cfg Package metadata for PyPI (name of your project, etc.)
README.md or README.rst ./README.md or ./README.rst Brief docs for your package to display on PyPI
.gitignore ./.gitignore Things you don't want in Git, including some build artifacts.
LICENSE or LICENSE.txt ./LICENSE or ./LICENSE.txt Project's license telling others how they can use your work
setup.py ./setup.py Technically optional, you'll want this so you can better develop locally

Package Cake Recipe 📋

  • Add one LICENSE or LICENSE.txt file. Picking a license can be tough, but there are tools to help like Choose A License.
MIT License

Copyright (c) 2021 Cake Packaging Foundation.

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.
Enter fullscreen mode Exit fullscreen mode
  • Add one pyproject.toml file. Unless you're building native code or using an alternative build system (i.e. poetry), you can copy and paste this.
[build-system]
requires = [
    "setuptools>=42",
    "wheel"
]
build-backend = "setuptools.build_meta"
Enter fullscreen mode Exit fullscreen mode
  • Add one setup.cfg. This is where you will specify the information that appears on PyPI and what is essential for your package to work.
# This is essentially a static version of setuptools.setup() and is the
# preferred method of indicating package metadata.
# https://packaging.python.org/guides/distributing-packages-using-setuptools/#setup-args

[metadata]
# A unique name for your package. Search through PyPI for duplicates.
name = packagecake

# Here you use SemVer for versioning - https://semver.org/
# You can also get fancy and pull this value from a file
# like so attr: packagecake.__version__
version = 1.0.0

# Your name or the organization's name. You can actually leave out the
# email and PyPI will still accept your package.
author = Example Author
author_email = author@example.com

# This is your sales pitch, your one-liner, your logline. Make it count
description = Turn your package into a delicious cake in less than 100ms

# Set this to the file you want displayed on PyPI.
# content-type can also be text/x-rst, or text/plain
long_description = file: README.md
long_description_content_type = text/markdown

# This will show in PyPI as your package's Homepage link
url = https://github.com/pypa/sampleproject

# These links will show up in PyPI under the Homepage link.
# Include at least Tracker.
project_urls =
    Tracker = https://github.com/pypa/sampleproject/issues
    Documentation = https://example.com/docs
    Source = https://github.com/pypa/sampleproject/
    Funding = https://example.com/funding
    Custom URL = https://example.com/

# Classifiers - https://pypi.org/classifiers/
# Make sure to include your license
classifiers =
    Development Status :: 3 - Alpha
    Intended Audience :: Developers
    License :: OSI Approved :: GNU General Public License v3 (GPLv3)
    Programming Language :: Python
    Programming Language :: Python :: 3
    Programming Language :: Python :: 3 :: Only
    Programming Language :: Python :: 3.8
    Programming Language :: Python :: 3.9
    Operating System :: OS Independent
    Topic :: Utilities

[options]
# Path to our libary/application
package_dir =
    = src
packages = find:

# Version of Python needed to use the package
python_requires = >=3.8

# Our package depends on these other external packages
install_requires =
    requests == 2.25.1

[options.packages.find]
where = src
Enter fullscreen mode Exit fullscreen mode
  • Add one README.md or README.rst. Briefly document your tool, giving users a taste of what they can do with it. Then point to your full length docs with a link. You'll want to save full length docs for another site as PyPI does have some limitations particularly with links to section headers. Alternatively, you can make a file just for PyPI and leave your README nice and detailed for your GitHub repo.
# Package Cake 🎂

**Package Cake** is a simple utility that takes your package and turns it
into a cake 🍰.

Checkout the [documentation](https://example.com/docs).

-> Add installation example here <-

-> Usage example here <-
Enter fullscreen mode Exit fullscreen mode
  • Add one .gitignore. You'll want to update your .gitignore file to exclude some of the build artifacts.
# Packaging
dist
build
*.egg-info/
Enter fullscreen mode Exit fullscreen mode
  • Add one setup.py. While setup.cfg handles static values, setup.py is for dynamic metadata. Favor setup.cfg whenever possible. You will however, want to use setup.py to help you test your package locally. Read on to see how you can test.
import sys

from setuptools import setup

if sys.version_info < (3, 8, 0):
    sys.exit("Python 3.8.0+ Required")

setup()
Enter fullscreen mode Exit fullscreen mode
  • Add one library or application. This is why you're publishing and you'll want to put this in a specific spot.
./src/[python package name]
    /__init__.py <- control your package's namespace
    /__main__.py <- optionally allow your package to be invoked from the command line
    /[your modules]
Enter fullscreen mode Exit fullscreen mode

Bake Until Built 🔥

Next you're going to build the package into a wheel and a source archive.

A wheel is a built distribution. If you have any binaries there will be pre-compiled copies in the wheel. This makes it a much faster process for users to get up and running with your package.

The source archive contains the raw source code of the package and let's pip or the user do any compilation locally instead. Wheels are generally preferred in most use cases.

  • Create a virtual environment

Unix/MacOS

cd [your project]
python3 -m venv venv
source venv/bin/activate
Enter fullscreen mode Exit fullscreen mode

Windows

cd [your project]
py -m venv venv
.\venv\Scripts\activate
Enter fullscreen mode Exit fullscreen mode
  • Install and run build. This will generate a ./build and ./dist directory in your project's root, along with creating a .whl and .tar.gz distribution package. Finally, you will also see a .egg-info directory in your ./src/[my project] directory.
pip install build
python -m build
Enter fullscreen mode Exit fullscreen mode
./build
./dist
    /packagecake-1.0.0-py3-none-any.whl
    /packagecake-1.0.0.tar.gz
./src/[python package name]
    /packagecake.egg-info
Enter fullscreen mode Exit fullscreen mode

Publish Your Package Cake 🌐

Now that our package cake is built you'll want to upload it to PyPI. I highly recommend testing your package configuration by first publishing to Test PyPI.

  • In your virtual environment install twine.
pip install twine
Enter fullscreen mode Exit fullscreen mode
  • Ensure the version number is properly incremented. You might keep the version number in setup.cfg, setup.py, or as __version__ in one of your other files. Make sure they all get updated.
   # setup.cfg
   [metadata]
   name = packagecake
   version = 1.0.1
Enter fullscreen mode Exit fullscreen mode
  • Create a PyPI account.

  • Create an API token from PyPI. Optionally setup a credentials file to store your API token.

# [user home directory]/.pypirc
[testpypi]
username = __token__
password = <my API token>

[pypi]
username = __token__
password = <my API token>
Enter fullscreen mode Exit fullscreen mode
  • Publish the package
twine upload dist/*

# For Test PyPI
twine upload --repository testpypi dist/*
Enter fullscreen mode Exit fullscreen mode

Taste the Package Cake 🍽️

You'll want to download and test the package now. Let's also look at how you can test before publishing.

  • Download and Verify the publish.
pip install packagecake

# For Test PyPI. No deps is safer, though you can only verify package contents
pip install --index-url https://test.pypi.org/simple/ --no-deps packagecake
Enter fullscreen mode Exit fullscreen mode
python
>>> import packagecake
🥮

# or if running from command-line

python -m packagecake
🍰
Enter fullscreen mode Exit fullscreen mode

And now what you can do before you publish. This let's you import and run your package as though it was downloaded with pip. It's called an editable package. You can then perform the steps you did above to verify the package.

python -m pip install -e .
Enter fullscreen mode Exit fullscreen mode

My First Python Package 🐣

I hope this helps you publish your package. A few quick resources I want to point out that helped me and of course a link to a package I built/baked 😊.

GitHub logo sirfuzzalot / pywhoami

A Simple HTTP Request Analysis Server

pywhoami logo

A Simple HTTP Request Analysis Server

PyPI Version Docs License: MIT Python Versions Code style: black

Pywhoami is inspired by the whoami Go server by Traefik Labs. Send a request to one of the endpoints to get back details from your HTTP request. With pywhoami you can help answer questions like, what headers were added to my original request by a proxy server.


Using the PyPI Package

Installation

bash

python3 -m pip install pywhoami
Enter fullscreen mode Exit fullscreen mode

powershell

py -m pip install pywhoami
Enter fullscreen mode Exit fullscreen mode

Running the Server

bash

>>> python3 -m pywhoami
[2021-04-17 15:00:25 -0700] [4400] [INFO] Running on http://127.0.0.1:8080 (CTRL + C to quit)
Enter fullscreen mode Exit fullscreen mode

powershell

>>> py -m pywhoami
[2021-04-17 15:00:25 -0700] [4400] [INFO] Running on http://127.0.0.1:8080 (CTRL + C to quit)
Enter fullscreen mode Exit fullscreen mode

Send it a test HTTP request.

Enter fullscreen mode Exit fullscreen mode

Cover Photo Credit: Domonique Davenport

Top comments (3)

Collapse
 
breadcrumb profile image
Brando

Haha this is great! Informative and fun to read! I love cake. 🍰

Collapse
 
sirfuzzalot profile image
sirfuzzalot

Glad you like it! Coding is always more fun with 🎂. My favorite is carrot cake. Whats yours?

Collapse
 
breadcrumb profile image
Brando

I love pineapple upside down cake. Carrot is good as well (^O^)