How I made the open-dev.to CLI app with Python
Tags: python, cli, learning, tutorial
Published: 2019-04-10 19:58:04

Since I began learning Python, I've been amazed by how much you can do with it, and how easy it actually is once you get comfortable with it. I've always loved working on the terminal, so to make my learning a bit fun, I learned how to make cli apps with [Click](https://click.palletsprojects.com/en/7.x/) and made a Chuck Norris jokes app late last year:

{%link https://dev.to/wangonya/norris-cli-4ifk %}

I posted the app on [PyPi](https://pypi.org) and as a Python beginner, you can just imagine my joy on seeing something _I_ did up on PyPi. PyPi! 😄 Awesome feeling.

Then yesterday, I had to take a break from work and decided to open Dev.to. I like to have my browser closed if I don't require it for whatever I'm doing to avoid distractions. So I switched workspaces, opened up my browser, clicked on the Dev.to bookmark and there I was. The idea just popped into my head: I could bypass all this if I had one command to open dev.to from the terminal. I was already on my terminal before anyway so this seemed like a good idea 😄. Of course, this could be done for any website - I just thought of Dev.to because that's what made me go through the process in the first place.

{%link https://dev.to/wangonya/open-dev-to-from-your-terminal-33g2 %}

As usual, the community was very supportive!

{% devcomment a2dk %}{% devcomment a2gm %}

So here's how I did it. 

In case you want to follow along, now's the time to create a new directory, `cd` into it, and create your virtual environment.

```console
$ mkdir open-dev.to
$ cd open-dev.to
$ virtualenv venv # pip install virtualenv if you don't have it
$ source venv/bin/activate
(venv) $ mkdir app
(venv) $ touch app/__init__.py # this is where we'll write our code
(venv) $ touch requirements.txt # this will hold the project's requirements
```

## `click` & the `webbrowser` module

At the heart of this whole thing is these two lines of code:

```python
import click
import webbrowser
```

[`webbrowser`](https://docs.python.org/3/library/webbrowser.html) provides the powers to open the browser, and [`click`](https://click.palletsprojects.com/en/7.x/) makes it a cli app.

`webbrowser` comes with python so all we need to install is `click`.

```console
(venv) $ pip install click
(venv) $ pip freeze > requirements.txt # add the installed module to our requirements file
```

Now that we have what we need, we can go ahead to write the code. Add the following code to `app/__init__.py`. I'll explain what each line does.

```python
import click
import webbrowser

@click.command()
@click.option('--tag', '-t', help='add a tag')
def main(tag):
    """
    Open a new dev.to browser tab on the browser
    """
    if tag:
        url = 'https://dev.to/t/{}'.format(tag)
    else:
        url = 'https://dev.to'

    webbrowser.open(url, new=2)

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

It's really that simple! Even a beginner would be able to make sense of what this code does.

**`@click.command()`**
This click decorator converts the `main()` function into a cli command. Without it, it would just be a normal python function. But with it, it becomes command that can be invoked as a command line utility.

**`@click.option('--tag', '-t', help='add a tag')`**
`@click.option()` extends the command to be able to accept extra arguments. In this case, `--tag` or its shorthand version `-t` is allowed. The `help` text explains what the argument does.

**`def main(tag):`**
This is our app's entrypoint, where all the magic happens. The function (now a command) takes an optional `tag` argument, which determines the url to be opened as seen in the `if else` a few lines below it.

**`"""Open a new dev.to browser tab on the browser"""`**
![comment](https://i.redd.it/iuy9fxt300811.png)

**`webbrowser.open(url, new=2)`**
Opens the requested url. `new=2` makes sure this is done in a new tab.

And finally, the `if __name__` block runs the `main()` function when the script runs.

Having the code above, just run the `__init__.py` to see it work.

```console
$ python app/__init__.py
```

A new Dev.to tab should automatically open on your browser.

```console
$ python app/__init__.py --help
Usage: __init__.py [OPTIONS]

  Open a new dev.to browser tab on the browser

Options:
  -t, --tag TEXT  add a tag
  --help          Show this message and exit.
```

Let's try out passing in a tag.
```console
$ python app/__init__.py --tag react
```

`https://dev.to/t/react` should be opened 😀.

We don't want to keep running `python app/__init__.py` everytime though. In the next post, I'll show how to use `setuptools` to bundle the script so we can install it locally and use the simple `dev.to` command to run the script instead of the long `python app/__init__.py`. I'll also show how to publish a package on PyPi.

![eliot](https://pbs.twimg.com/profile_images/1048098761552142336/goBBdAW1.jpg)