This Script is Only Useful to Me (Probably)
Tags: python, showdev, discuss, motivation
Published: 2022-03-03 02:26:34


I have a podcast with a friend and we were interested in uploading our episodes in full to YouTube. Unfortunately, he doesn't know how to video edit and I'm busy with my job, streaming, the podcast, and writing articles like this, so it seemed like YouTube as a podcast platform was dead to us. I did a bit of research and it turns out both our podcast platform Buzzsprout and YouTube have APIs available for uploading, which meant if I invested the time, I could bundle up the uploading work in to one script and have it done even faster.

Then the classic dilemma hit me -- do I really want to sink the time in to doing this? There's so many factors that go in to that like how much time it'll save me, how much time it'll take, will anyone else find it useful. Ultimately, I hit upon the piece of logic I often hit on when deciding what personal projects to do -- it sounds fun so why not?

## Three Scripts
First off, I decided to write three separate scripts to do the following operations:

- Upload the podcast to Buzzsprout
- Create a visualization video for the podcast. Essentially a static image with audio visualization on top with the podcast as the audio
- Upload a video to YouTube

All three on their own are small, atomic operations that can be stitched together with an overarching script or CI/CD platform to form a complete workflow, but can also be used individually. Since the upload data required for both Buzzsprout and YouTube are similar (time to publish, title, description, and episode number), it makes sense to streamline the input of data in to both upload scripts and call the script just once.

## Podcast Workflow Automator
Copying and pasting the code from all three scripts and making one super script does future me a disservice. By smashing them together, but also having them separate, any changes in one code base needs to also be copy/pasted in to the other code base and if I don't remember that, I'll end up fixing bugs or coding enhancements twice. As mentioned earlier, I could have one base script and call these individual scripts on their own via Bash, Powershell, or a CI/CD platform, but since Python also allows you to import code from other `.py` files, I decided to keep it consistent and go for that option.

## Prepping individual scripts for import
Unfortunately, the way in which I usually write standalone scripts isn't compatible with import, so a few changes had to be made. Upon initially writing the scripts, my code looked like this:

```python
def main():
  parser = argparse.ArgumentParser()
  parser.add_argument("--foo")

  # script logic

if __name__ == "__main__":
  try:
    main()
```

This structure doesn't allow us to use the meat and potatoes of the script without grabbing arguments from `argparse`. To fix this, we pull all the `argparse` logic in to its own function, then call the main function from that. The `main` function is also renamed to something more logical so when we're importing it in other functions, we're not scratching our heads wondering what `main` does.

```python
def call_with_args():
  parser = argparse.ArgumentParser()
  parser.add_argument("--foo")
  
  args, _ = parser.parse_known_args()
  upload_podcast(args.foo)

def upload_podcast(foo):
  # upload logic


if __name__ == "__main__":
  try:
    call_with_args()
```

Now that our relevant functions have been renamed, we can move on to exposing and importing them in to our new script. First off, the base script needed to be moved to a directory with the name I wanted to use for the package. Next an `__init__.py` file had to be created alongside the script that imported and exposed the primary function as part of being a module. Then a `setup.py` file detailing the package and its dependencies had to be created in the base directory. All of that is to enable importing in the `requirements.txt` like this:

```
git+https://github.com/codingvibe/audio-to-vizualization@main#egg=audio_to_visualization
git+https://github.com/codingvibe/buzzsprout-uploader@main#egg=buzzsprout_uploader
git+https://github.com/codingvibe/youtube-uploader@main#egg=youtube_uploader
```

Now we can import the relevant functions in to our combined script like any normal package this:

```python
from buzzsprout_uploader import upload_podcast
from audio_to_visualization import create_vizualization
from youtube_uploader import upload_video
```

Was this a non-trivial amount of work to do for something nobody is likely going to use? Yes. Are there easier, dirtier ways to do this? Absolutely. Since I have the repos locally, I could have just done this:

```python
sys.path.append('../')

from buzzsprout_uploader.buzzsprout_uploader import upload_podcast
from audio_to_visualization.audio_to_visualization import create_vizualization
from youtube_uploader.youtube_uploader import upload_video
```

Had I done this, I wouldn't have had to bother with the `script.py` or package directory. I decided to go with the pip-importable way just to get some experience doing it and on the off chance anyone else would use this. Had I not intended to upload it to Github, I definitely would have done it the lazy way (and in fact I did on my [Twitch stream](https://www.twitch.tv/codingvibe) and only made it importable when I wrote this article). Doing it the "right" way took quite a while and lead to this fun experience:

{% embed https://twitter.com/CodingVibe/status/1498493630411157507 %}

## Final Thoughts
Is this a project more people can use than just me? Maybe, but honestly it doesn't matter -- it's going to make my life marginally easier and was fun to write. I spent probably 20 hours taking my time to upload an episode to Buzzsprout and YouTube from 20 minutes to 5, which means it'll be worth the time investment once we have 80+ episodes. As the saying goes, "why spend 10 minutes doing a task when I can spend 3 hours automating it?"

The three individual scripts you can find here:
{% embed https://github.com/codingvibe/audio-to-vizualization %}
{% embed https://github.com/codingvibe/buzzsprout-uploader %}
{% embed https://github.com/codingvibe/youtube-uploader %}

And the final workflow script is here:
{% embed https://github.com/codingvibe/podcast-workflow-automator %}