rust-ssg/blog/posts/2021-11-04_python3-github-cli-tool-as-a-refresher.rst

38 lines
4.0 KiB
ReStructuredText
Raw Normal View History

2023-10-14 18:03:36 +00:00
Python3 GitHub CLI tool as a refresher
######################################
:date: 2021-11-04 01:29
:author: tyrel
:category: Tech
:tags: python, cli
:slug: python3-github-cli-tool-as-a-refresher
:status: published
It's no lie that I love terminals. I wish I could live on a terminal and never really need to see a GUI application again.
Last night I migrated a lot of my old code from one GitLab account to another (`tyrelsouza <https://gitlab.com/tyrelsouza>`__ to `tyrel <https://gitlab.com/tyrel>`__) in an effort to clean up some of my usernames spread across the world. While doing that I noticed my `django-dbfilestorage <https://gitlab.com/tyrel/django-dbfilestorage>`__ Python module that has been sitting and rotting for three years. I played around a little bit in order to port it to Python 3.9, but I ran into some base64 errors. I tried a little bit but it was late and I couldn't figure it out. My resolve is that I have been away from Python for too long so the little things - that I knew and love - had fallen away. I mentioned this to my friend Alex and he said *"make a barebones github cli (readonly?) with issue viewer, and stats display"*. I've embarked on a journey to refresh my Python well enough to repair DBFS.
.. figure:: {static}/images/2021/11/github_cli-alex_prompt.png
:alt: Me: "okay python frioends, what should I make as a quick refresher into the Python world?" alex: "maybe: barebonx github cli (reasdonly?) with issue viewer and stats display"
I knew I wanted to use ``httpx`` as my network client library, it's new, fast, and I have a couple friends who work on it. I started with a barebones ``requirements.in`` file, tossed in ``invoke``, ``pytes``\ t, and ``black``. From there I used ``pip-compile`` to generate my ``requirements.txt`` - (a tip I picked up recently while adding Pip-Compile support to the `Tidelift CLI <https://tidelift.com/cli>`__) and I was good to go.
The `docs for the GitHub API <https://docs.github.com/en/rest/overview/resources-in-the-rest-api#schema>`__ are pretty easy to read, so I knew all I really needed to do was set my ``Accept`` header to be Version3 and I could view the schema. With the schema saved to a ``.json`` file I then wrote a ``GHub`` class to pull this data down using ``httpx.client.Client.get``, super simple! The only two endpoints I care about right now are the user and repos endpoints, so I made two ``get_`` functions for each. After a little bit of work - which I won't bore you with the super intricate details - I have a functional cli.py file. For now, the only interaction is a propmt from ``rich`` for a username, and then you get a fancy table (also from ``rich``) of the first page of results of repos, stargazer/watchers/forks counts, and a description.
.. figure:: {static}/images/2021/11/github_cli-prompting_and_table.png
:alt: Prompting for the username and showing my table of repositories.
Prompting for the username and showing my table of repositories.
It was a fun evening of learning what's changed in Python3 since I last touched it, especially as I've spent the majority of my career in Python2.7. Type annotations are super awesome. I'll probably pick it up again once I get some more free time later in the week. It's also nice blog fodder! I already have a million things I want to do next - pagination, caching, some more interaction.
.. figure:: {static}/images/2021/11/github_cli-pytest_running.png
:alt: Showing py.test running
Showing py.test running
I know the tool I'm writing is nothing special, especially with their own `cli <https://github.com/cli/cli>`__ now, but I'm not looking at reinventing the wheel!
Check out the code so far on my `GitLab <https://gitlab.com/tyrel/ghub>`__ (*heh*, ironic it's there).
Dependencies: `httpx <https://www.python-httpx.org/>`__, `pip-tools <https://github.com/jazzband/pip-tools>`__, `black <https://github.com/psf/black>`__, `invoke <https://www.pyinvoke.org/>`__, `pytest <https://docs.pytest.org/en/6.2.x/>`__, `pytest-httpx <https://pypi.org/project/pytest-httpx/>`__, `rich <https://github.com/willmcgugan/rich>`__.