Fun with Python: A Command-Line URL Shortener

Hey everyone,

It's time for another "Fun with Python" post. I was recently reminded that Google discontinued its goo.gl URL shortening service a while back. While there are plenty of web-based alternatives, I thought it would be a fun and useful project to build a simple, no-fuss URL shortener that I can run right from my command line.


The goal was to create a script that takes a long URL, sends it to a free shortening service, and gives me back a short link that's also copied to my clipboard.

For this project, I used the TinyURL API because it's incredibly simple and doesn't require any authentication keys. The script uses the requests library to talk to the API, pyperclip to handle copying to the clipboard, and rich for some nice, clean output in the terminal.

Here's the complete script:

#!/usr/bin/env -S uv run --quiet --script
# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "requests",
#     "pyperclip",
#     "rich",
# ]
# ///

import argparse

import pyperclip
import requests
from rich.console import Console

# --- Configuration ---
CONSOLE = Console()
# TinyURL has a simple, no-auth API endpoint
API_URL = "http://tinyurl.com/api-create.php"


def shorten_url(long_url: str) -> str | None:
    """Uses the TinyURL API to shorten a given URL."""
    try:
        response = requests.get(API_URL, params={"url": long_url}, timeout=10)
        response.raise_for_status()
        return response.text
    except requests.RequestException as e:
        CONSOLE.print(
            f"[bold red]Error: Could not connect to the shortening service: {e}[/bold red]"
        )
        return None


def main() -> None:
    """Main function to run the link shortener."""
    parser = argparse.ArgumentParser(
        description="A simple command-line URL shortener using TinyURL."
    )
    parser.add_argument("url", help="The long URL to shorten.")
    parser.add_argument(
        "-n",
        "--no-copy",
        action="store_true",
        help="Do not copy the shortened URL to the clipboard.",
    )
    args = parser.parse_args()

    long_url = args.url
    # A simple check to ensure the URL has a scheme
    if not long_url.startswith(("http://", "https://")):
        long_url = "http://" + long_url
        CONSOLE.print(f"[dim]Assuming http scheme: {long_url}[/dim]")

    with CONSOLE.status("[bold green]Shortening URL...[/bold green]"):
        short_url = shorten_url(long_url)

    if short_url:
        CONSOLE.print("\n[bold green]✓ Success![/bold green]")
        CONSOLE.print(f"  [bold]Original:[/bold] {args.url}")
        CONSOLE.print(f"  [bold]Shortened:[/bold] [bold cyan]{short_url}[/bold cyan]")

        if not args.no_copy:
            try:
                pyperclip.copy(short_url)
                CONSOLE.print(
                    "\n[dim]Shortened URL has been copied to your clipboard.[/dim]"
                )
            except pyperclip.PyperclipException:
                CONSOLE.print(
                    "\n[yellow]Warning: Could not copy to clipboard. Is 'xclip' or 'xsel' installed?[/yellow]"
                )


if __name__ == "__main__":
    main()

To test it out, I grabbed the URL from one of my recent posts on PeakD. The result is a clean, short link, ready to be shared. https://tinyurl.com/2557neuj

shorten.png

It's a small, practical tool that takes care of a common task, which is what these "Fun with Python" projects are all about.

As always,
Michael Garcia a.k.a. TheCrazyGM

0.11522298 BEE
2 comments

That's a nifty tool! I don't know if I've ever had a need to shorten a URL. How and why do people use them? I'm just curious. 😁🙏💚✨🤙

0.00024865 BEE

Well, the original reason they were created was to share really long links in places like twitter where there was a character limit.

The main use them now, but you have login to do, is to see who has clicked your link, how many times, and all the other data gathering metrics people use for things like newsletters, marketing campaigns etc.

Then, there is of course the potential for malicious use: https://tinyurl.com/2fcpre6

0.00000340 BEE

Ah, OK, now that definitely makes sense for short-form platofrms.

Oh, yes, that I can definitely see as well. I'm sure lots of people use it for that reason indeed.

That's actually the very first thing that came to my mind around their use, and one of the reasons that I don't usually click on them, unless I trust the individual who sent it to me. 😁🙏💚✨🤙

0.00000000 BEE

Congratulations @thecrazygm! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You received more than 6000 HP as payout for your posts, comments and curation.
Your next payout target is 7000 HP.
The unit is Hive Power equivalent because post and comment rewards can be split into HP and HBD

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Check out our last posts:

0.00024390 BEE