How to publish a python package - Best Practices: A YouTube Channel API Example
Tags: python, tutorial, programming, api
Published: 2024-01-10 08:48:06

Hey everyone! 👋

We've finally wrapped up our coding journey with [The Better YouTube Channel Details API](https://rapidapi.com/dataocean/api/the-better-youtube-channel-details). It's been a real adventure getting all those YouTube channel details like social media links, email addresses, avatars, RSS feeds, and subscriber stats.

Guess what? It's time to roll out our baby to the world - we're hitting PyPi with our package! It's not just about bragging rights; we're here to lend a hand to fellow coders. We've cooked up this nifty library so you can plug it into your apps without breaking a sweat. Cheers to smoother coding days ahead!

1. [creating the package structure and writing code to communicate with the API](https://dev.to/apiharbor/building-python-package-api-client-for-youtube-channel-details-rapidapi-75g)
2. [testing the solution](https://dev.to/apiharbor/get-youtube-channel-details-api-connection-testing-1jjg)
3. 👉 **we are here: publishing our work on pypi.org**

## setup.py - necessary information about the package

So let’s create the `setup.py` file directly in the project directory

![setup.py](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wppjvc9gmtyc4n05uzbr.png)

We will be using a template like the one below. It contains all the important information, so in my opinion, this example has everything we need:

```python
from setuptools import setup, find_packages

setup(
    name='example',
    version='0.1.0',
    author='author',
    author_email='author@example.com',
    description='short description',
    long_description=open('README.md').read(),
    long_description_content_type='text/markdown',
    url='https://example.com',
    packages=find_packages(),
    install_requires=[
        # Package dependency list, e.g 'requests >= 2.20.0'
    ],
    classifiers=[
        'Programming Language :: Python :: 3',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
    ],
    keywords=['example'],
    python_requires='>=3.6',
)
```
We will closely examine the setup and present the best practices for each property!

## Best Practices

### 👉 Name

**Simplicity is Key**: Pick a name that's easy to remember and reflects your package's functionality.

**Check for Uniqueness**: Make sure your chosen name isn't already in use on PyPI to avoid naming conflicts.

**Lowercase Preference**: Typically, Python package names are all lowercase, following a common Python packaging convention.

**No Special Characters**: Use only letters, numbers, and underscores. Avoid characters like hyphens, as they can make importing the package more difficult.

**Descriptive and Relevant**: Choose a name that gives a hint about what your package does. Steer clear of names that are too generic or ambiguous.

**Concise and Memorable**: Aim for a name that's short and sticks in the mind. Long or complex names can be hard to remember.

**Avoid Trademark Issues**: Make sure your package name doesn't infringe upon existing trademarks or brand names.

### Our choice:

> Following the instructions above, we are leaning towards the name: apiharbor_youtubeapi, because it combines username with "youtube" and "api," clearly indicating its purpose and origin.

## 👉 Version

Choosing the right version number for your Python package is important for effective version control and to communicate the nature of changes to users. Here are some best practices for versioning your package:

### Use Semantic Versioning (SemVer):

**Major Version (X.y.z)**: Bump this up when you make big changes that aren't backward compatible. Think of it as a 'new era' for your package.

**Minor Version (x.Y.z)**: Increase this when you add cool new features, but everything old still works fine.

**Patch Version (x.y.Z)**: This one's for those little bug fixes and tweaks that don't change the features.

**Starting Point**: If your package is all grown up and stable, kick off with 1.0.0. If it's still a baby (in early development), start with something like 0.1.0.

**Pre-Release Fun**: Got a beta or alpha version? Tag it onto the end like 1.0.0-beta. It's like giving your users a sneak peek.

**Post-Release Adjustments**: Need to tweak a release without a big fuss? Use post-releases like 1.0.0-1 for those minor changes, maybe a typo fix in your documentation.

**Changelog Is Your Friend**: Keep a log of what you change or fix. It's super helpful for users and fellow developers to track what's new or different.

**Stay Consistent**: Picked SemVer? Great! Stick with it. Consistency is key.

**No Wild Jumps**: Avoid crazy jumps in version numbers. Each increment should make sense.

**Define Your Public API**: Make it clear what's in your public API and how you plan to keep it stable. This guides your versioning strategy.

Remember, version numbers are like signposts for users – they tell them what to expect with each new update. Keep it clear and sensible!

### Our choice:

> We will set version `1.0.0` as it is the first production version. Later, we will adhere to the semantics and best practices mentioned above.

## 👉 Author
You might be wondering, it's just the `author` field, what could be important here? Choosing the right author can actually be a challenge. Here are some best practices to follow when specifying an author:

**Go Real with Names**: Using your real name adds a touch of professionalism and trust. If you're in a team, you might want to list the lead dev or the project boss.

**Keep It Uniform**: Got a bunch of packages? Stick to the same name across the board. It helps users and contributors spot your work in different places.

**Shoutout to Co-Authors**: Working with a cool team? Give them a nod. But remember, the `author` field usually has just one name or entity. You can always detail everyone else's contributions in a CONTRIBUTORS file or the docs.

**Representing an Org**? Use Its Name: Publishing on behalf of a company, university, or open-source group? Use that name. It's pretty standard for projects developed under an official banner.

**Emails: Handle with Care**: Including an email? Make sure it's one you set up for the project or can handle public emails. Watch out for spam risks!

**Privacy Matters**: If you're worried about privacy or other personal issues, a pseudonym is totally fine. Just keep it professional and consistent.

**Change of Guard? Update the Name**: If there's a new sheriff in town (aka a new maintainer), update the author field. Maybe give a shout out to the original author in the docs.

**Stay Professional**: This field is out there for all to see in package directories and repos. A professional touch can really make a difference in how people view your package's reliability.

Remember, the way you present the author info can say a lot about your package. Keep it clear, respectful, and professional!

### Our choice:

> As we can see, `author` is not so obvious, but in our case, we will simply set it to: `apiharbor`. However, it's good to be aware of the things mentioned above.

## 👉 Description
A very important thing. The description must attract developers and encourage them to install our package. After all, we want to clearly show them that using our library will make their lives easier. What should guide us? Here are our best practices:

**Short and Sweet**: Nail your description in just a few words. It should quickly let users know what your package is all about, in plain language.

**Keyword Magic**: Sprinkle in those relevant keywords. They're like beacons for users and search engines, guiding them to what your package offers.

**Jargon? Just Say No**: Unless you're talking to a niche crowd, keep the tech talk to a minimum. Clear and simple is your best bet.

**Showcase the Wow Factor**: What's special about your package? Does it solve a tricky problem? Add a sparkle to something ordinary? Let that shine through.

**Grammar Police**: Polish your description. No typos, no grammar bloopers. It's like dressing your package for success.

**Language Harmony**: Stick to one language. If your code comments and docs are in English, your description should be too.

**Tone It Right**: Keep the vibe professional, tailored to who you're talking to.

**Stay Current**: Evolved your package? Give your description a makeover too. Keep it in sync with what's new or different.

**Keep It Real**: Don't oversell. Promise what you can deliver, or you might end up with unhappy users.

**Build Trust**: Especially for packages aimed at a broad audience, your description should radiate confidence about your package’s stability and usefulness.

Remember, your description is like the front door to your package. Make it inviting, clear, and true to what's inside!

### Our choice:

> Following these practices, we will set the description:

> Want to dive deeper into the YouTube scene? Our YouTube Channel Details API is just what you need, especially if you're a marketer, researcher, or content creator. It's not just about getting contact info; it's about discovering those little gems like social media and location details of YouTube channels. Imagine the possibilities - like when one of our users found the perfect collaboration opportunity just by using these insights!

A big advantage of it is that it's short and clear to understand. Right away, you can see who it's intended for and what it does.

## 👉 Long Description
Here are two properties to be filled

`long_description=open('README.md').read()` -  path to the README file
`long_description_content_type='text/markdown',` - content format

Let's take a look at the best practices we use.

**Snappy Title**: Kick off with a title that's both clear and catchy. It should give a snapshot of what your project is all about.

**Elevator Pitch Description**: In just a few sentences, highlight what your project does and its coolest features. Think of it as your project's elevator pitch.

**Easy-Peasy Setup**: Guide your users through a hassle-free installation. Simple steps, commands to run, or download links will make it a breeze.

**How-to-Use Demo**: Show off how your project works. Include code snippets, command-line examples, or even screenshots for a quick visual guide.

**Dependencies List**: Got other tools or libraries your project leans on? List them out clearly along with installation tips.

**Config 101**: If your project needs some setting up, walk your users through it with detailed instructions.

**Test Run**: If your project has automated tests, explain how to run them. It's like a health check for your project.

**Join the Club**: Invite others to contribute and lay out the ground rules in your CONTRIBUTING.md. Collaboration makes the project world go round!

**Version Chronicles**: Talk about your versioning system, if you have one. It's like telling the history of your project's evolution.

**Cheers to the Team**: Acknowledge the brains behind the project. List the authors and give a shout-out to contributors.

**License Lowdown**: Include your project's license details – a brief note and a link to the full text should do the trick.

**FAQs Corner**: Tackle those frequently asked questions or common hiccups users might run into.

**Got Questions? Get in Touch**: Provide contact info for support or inquiries. It's always nice to have someone to reach out to.

**Badge Bonanza**: (Optional) Flaunt those badges! They're like little trophies showing off your project's health or status.

**Show and Tell**: If it makes sense, add visuals like screenshots, gifs, or videos to showcase your project in action.

**Global Reach**: If your project speaks multiple languages, mention the available translations and how to switch them.

**What’s Next?** Got plans for your project? Share your roadmap or future dreams – it's exciting to see where things are headed.

Remember, your project documentation is your chance to make a great first impression. Make it friendly, informative, and engaging!

### Our choice:

> We won't paste the content here because it would be a bit (just a tad ;)) over the top, but I encourage you to check out our [README.md](https://github.com/apiharbor/apiharbor-rapidapi-dataocean-python-youtubeapi/blob/main/README.md)

## 👉 Keywords

Keywords are the last property we'll discuss, as the rest is purely technical and there's nothing groundbreaking there, you just need to set the remaining values correctly 😊 and that's it.

Our best practices for selecting keywords are:

**Spot-On Selection**: Pick keywords that are like a bullseye for what your project is all about. Think of functionality and purpose.

**Nail the Specifics**: Choose terms that precisely paint a picture of what your project can do. It's like giving someone a mini-tour through its features.

**What Would Users Type?**: Think about the words your future fans might use when they're on the hunt for a project like yours. Those are your golden keywords.

**Mix It Up**: Blend both broad and narrow terms. It's like casting a wide net, but with some targeted spots.

**Quality Over Quantity**: It’s tempting to throw in a kitchen sink of keywords, but resist the urge. A well-thought-out, concise list is way more effective. Aim for that sweet spot where you've covered the essentials without going overboard.

Remember, picking the right keywords is like setting up signposts that lead straight to your project. Make them count!


Our choice:

```python
keywords = [
    "youtube",
    "api",
    "youtube-api",
    "channel-details",
    "youtube-data",
    "youtube-analytics",
    "contact-information",
    "social-media-analysis",
    "youtube-marketing",
    "content-creation",
    "influencer-research",
    "video-analytics",
    "youtube-content",
    "media-analysis",
    "digital-marketing"
]
```

That will be perfect 🙂

## Let's put everything together

```python
from setuptools import setup, find_packages

setup(
    name='example',
    version='0.1.0',
    author='author',
    author_email='author@example.com',
    description='short description',
    long_description=open('README.md').read(),
    long_description_content_type='text/markdown',
    url='https://example.com',
    packages=find_packages(),
    install_requires=[
           ],
    classifiers=[
        'Programming Language :: Python :: 3',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
    ],
	keywords=['example'],
    python_requires='>=3.6',
)
```

## Publishing the Package!

The first thing we need to do is register at [PyPi](https://pypi.org/)

Then, we launch the command line and navigate to the directory where we have `setup.py`. Next, we run a command to ensure we have the latest installation package installed:

`\ApiHarbor\libs\youtube_channel_details_api>python -m pip install --upgrade build`

Now, we need to generate the distribution archives that we will publish. We do this using the command:

`python -m build`

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7fmooynbjy20viv9fmmi.png)

![project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t2h1aexm86tamjwc48jr.png)

The build has finished. Let's check if everything was generated correctly by entering the command:

`twine check dist/*`


![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nrk3wxyiawqh6s3e9hjj.png)

Everything looks great!

Now that we have the distribution files, we need to install `twine` as it's needed to upload the distribution package. We enter the installation command:

`python -m pip install --upgrade twine`

### ✋ Token needed!

PyPi has changed its authentication system. Now, we won't publish by providing our username and password for the account, but we need to do it through API tokens.

First, we need to create the token by entering here:
[https://pypi.org/manage/account/token/](https://pypi.org/manage/account/token/)


![creating a token](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dg2b90ahmf12babhf8ge.png)

Then, let's save it somewhere on the side so we don't lose it.


![token](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zttan9f5oc3gmhfoaqdh.png)

Now, the most important part, the command to publish our package:

`python -m twine upload --repository pypi dist/*`

After entering the command, you will be prompted to enter the username. There, you should type: `__token__`
yes, `__token__`, always enter `__token__`

and the password, which is the previously saved token, including the prefix: `pypi-`
This is very important

Note! If we want to publish on `testpypi`, we need to create an account (register) at https://test.pypi.org/

`pypi` (production) and `testpypi` (test) are separate from each other, so the generated tokens will not work in both places. This needs to be kept in mind, because during the upload, we might encounter a situation where we provide the correct auth data but still receive the response:

`HTTPError: 403 Forbidden from …`

## Summary

That's all from our series of posts about creating and publishing your own Python package. We went through the journey from setting up the project structure, writing the code, and its tests, to publishing the package. Now, programmers around the world can breathe a little easier thanks to us.

You can see our work here:
- [Published package on PyPi](https://pypi.org/project/apiharbor-youtubeapi/1.0.0/)
- [Package source code](https://github.com/apiharbor/apiharbor-rapidapi-dataocean-python-youtubeapi)
- [Our Website with interesting articles about APIs](https://apiharbor.com/)

💚 Thanks for your time and see you!

p.s. I hope you enjoyed the style and examples. If possible, please give a thumbs up, comment, or any kind of reaction! It fuels me for future posts. Follow me to make sure you don't miss anything 🚀