From Local Code to PyPI: Publishing My First Tool
In my previous post, I shared the story of building my first OSINT tool — UserRecon.
In this post, I want to share something equally important:
how I published this tool on PyPI, and why that journey felt like a tragedy-based comedy.
“What Should I Do Next?”
As soon as I finished building the tool, I did what most of us do nowadays.
I opened ChatGPT and asked:
“I have made this tool. What should I do next?”
The answer was simple:
“Publish it on GitHub.”
So I did exactly that.
Then I asked again:
“I also want to publish it on the apt store. Give me step-by-step guidance.”
After reading the response, I realised something important.
Publishing on apt would be too heavy for me right now. For a beginner, PyPI was a much better starting point.
And that’s how my PyPI journey began.
Tragedy + Comedy = PyPI
The first step was extremely simple:
Sign up on pypi.org
The real journey started after that.
Before anything else, I needed to understand the project structure required for PyPI.
Once I saw it, I realised I was missing one important file:
Naturally, the next question in my head was:
“What exactly is setup.py?”
Understanding setup.py
ChatGPT gave me a basic template for setup.py, which helped.
But I still wanted clarity, so I Googled it.
In simple words, I understood this:
setup.py contains metadata about the tool and its developer.
It includes:
-
tool name
-
version
-
description
-
dependencies
-
installation details
Once I wrote setup.py and set the version to 1.0.0, I moved forward.
Building the Project (and Testing My Patience)
I opened the terminal at the root of the project and ran:
That second command…
was the real patience test.
I got my first error.
It was completely unreadable.
I copied the error and pasted it into ChatGPT.
The response shocked me:
“You do not have a README.md file.”
I did have a README.
So I pasted my README content into ChatGPT.
That’s when the comedy hit.
The issue wasn’t the README itself —
I had used ''' (triple quotes) instead of ``` (backticks) for code blocks.
Such a silly mistake ๐
I fixed it and ran the build command again.
Another Error. Of Course.
This time the error said:
README.md is not included in the source distribution.
That’s when I learned something new.
A PyPI build has two parts:
-
sdist(source distribution) -
wheel
To tell PyPI that README.md is part of the source, I had to create a new file:
And include:
After that, the build finally succeeded.
(Of course, I ran it again just to be sure.)
Uploading to PyPI (Yet Another Test)
Now came the upload step:
It asked me for an API key.
And I was like:
“For what? From where?” ๐คจ
Answer:
From your PyPI account.
So I created an API key.
During this whole process, PyPI kept asking for passwords — and as cybersecurity people, we all know how simple and memorable our passwords are ๐ต๐ซ.
Eventually…
the tool was uploaded.
“It Installed… But Didn’t Work”
I tested it by running:
And boom — error.
But it worked perfectly on my local system.
After debugging, I realised the issue:
I hadn’t created an __init__.py file.
Locally, it worked fine.
But PyPI expects package structure to be explicit, even if the file is empty.
So I added an empty __init__.py, bumped the version to 1.0.1, and uploaded again.
One More Bug (Last One, I Promise)
After installing again, I hit another error.
This time it said:
Module
platformsnot found.
I was confused.
The module existed and worked locally.
After checking everything, ChatGPT pointed out the issue:
When importing a module from the same package, PyPI expects relative imports.
So instead of:
I had to use:
These mistakes forced me to upload four different versions of the same tool.
The Moment It Finally Worked
When everything finally worked —
installation, execution, imports — I genuinely couldn’t hold it in.
I banged the table and said:
YES. I DID IT. ๐
Final Thoughts
Publishing on PyPI taught me more than writing the tool itself:
-
how packaging works
-
how environments differ
-
why “works on my machine” is not enough
-
and how patience is part of engineering
I’ll be back with another post —
Until then:
-
keep breaking things
-
keep fixing them
-
and don’t fear mistakes — they’re part of the build.
Comments
Post a Comment