For OSD600 Lab 9, I took on the challenge of releasing my open-source project to the world. My goal was to take my code and package it so that anywhere I can install it with a single command.
I chose to package my Python project, repo-code-packager, and publish it to PyPI (Python Package Index)
The Tools
Since I am working within the Python ecosystem, I used the standard industry tools for packaging:
- PyPI: The official third-party software repository for Python.
- build: A standard tool to create distribution packages.
- twine: A utility for publishing Python packages to
PyPIsecurely. - pyproject.toml: The modern configuration file for defining package metadata and build system requirements.
The Process
Preparing the Package The first step was organizin…
For OSD600 Lab 9, I took on the challenge of releasing my open-source project to the world. My goal was to take my code and package it so that anywhere I can install it with a single command.
I chose to package my Python project, repo-code-packager, and publish it to PyPI (Python Package Index)
The Tools
Since I am working within the Python ecosystem, I used the standard industry tools for packaging:
- PyPI: The official third-party software repository for Python.
- build: A standard tool to create distribution packages.
- twine: A utility for publishing Python packages to
PyPIsecurely. - pyproject.toml: The modern configuration file for defining package metadata and build system requirements.
The Process
Preparing the Package
The first step was organizing my project structure and creating the pyproject.toml file. This file is the heart of the package, containing the name, version, author info, and dependencies. I had to ensure my source code was properly structured in a src directory with __init__.py files to make it importable.
1.
Building and Tagging
I used the python -m build command to generate the distribution artifacts. Before releasing, I practiced using Git Tags, marking my repository with v0.9.0 to simulate a pre-release state. Once I was ready for the official launch, I bumped the version to v1.0.0 and pushed the tags to GitHub.
1.
Publishing to PyPI
Uploading was surprisingly straightforward using twine. I generated an API Token from PyPI for security and used it to authenticate during the upload process.
python -m twine upload dist/*
Seeing my package live on PyPI for the first time was a exciting moment.
Unexpected Challenges However, the road to a stable release wasn’t smooth. I learned that publishing is easy, but publishing correctly is hard.
The Case Sensitivity Trap
My biggest problem came from directory naming. My source folder was named Repo_Code_Packager, but I used repo_code_packager for project name. When I released the package, I realized that users had to import it exactly as the folder was named:
# correct
from Repo_Code_Packager.content_packager import ContentPackager
# wrong
from repo_code_packager.content_packager import ContentPackager
This taught me the importance of adhering to naming conventions before starting a project. For this release, I updated the documentation to clearly instruct users to use the capitalized import.
Missing Dependencies and Class Structures
In my initial v1.0.0 release, I missed declaring Pygments as a dependency in pyproject.toml. This meant users installed my package but crashed immediately upon running it. I also realized my code was a collection of loose functions, which was hard for users to integrate. I quickly refactored the code into a proper ContentPackager class, added the missing dependency, and released patches v1.0.1 and v1.0.2, to fix these issues.
User Testing To verify my release, I asked my cousin, who is also a software developer, to test the package. This session was incredibly valuable.
I provided him with the PyPI link and my README.md.
- The Install: He successfully installed it using
pip install repo-code-packager. - The Confusion: He instinctively tried to import it using lowercase and hit an
ImportError. I had to point out that the directory name required uppercase. - The Fix: Seeing him struggle with the
importconfirmed that I needed to update my documentation immediately to highlight the case-sensitive import statement.
It was a great reminder that documentation is just as important as the code itself.
This lab taught me that software release is an iterative process. It’s rare to get v1.0.0 perfect on the first try, and that’s okay. Tools like twine and semantic versioning allow us to fix and improve our packages continuously.