A Slight Walkthrough My CLI

Loren Cipriano
6 min readJan 10, 2021

There are two ways I could’ve created my first CLI project for Flatiron School. First let’s talk about what a CLI is, “Command-line interface (CLI) is a text-based interface that is used to operate software and operating systems while allowing the user to respond to visual prompts by typing single commands into the interface and receiving a reply in the same way.”. To create a CLI one could Scrape a website for the information that will be used for your project or two, use an API. Scraping would be writing your own code from scratch and taking only the data you would like to utilize. As an API (Application Programming Interface) would have data and functionality all in one. I found wiki’s definition most simply described; “An application programming interface (‘API’) is a computing interface that defines interactions between multiple software intermediaries. It defines the kinds of calls or requests that can be made, how to make them, the data formats that should be used, the conventions to follow, etc.”

To start my project I had to pick and choose which API to use. I decided on what my CLI was going to be after I carefully review the available API on this website: https://github.com/public-apis/public-apis. I found it easier to select an API first rather than coming up with a topic first. I knocked my choices down to two APIs, either a Covid-19 cases per country or the popular Game Of Thrones API. Extremely moved by the covid-19 cases due to my health-care background but ultimately I decided there was no need for a reminder of this year's misfortunes.

Everything I will be mentioning in this quick overview will be sourced down below.

First, created my CLI by running ‘bundle gem’ in my terminal like so for a “quick start”. (Check outsources for more info)

bundle gem <name> 

Next, I set up and updated my required files and added gems I’ll be using, and deleted codes and files that were not needed.

Once I’m done with my set up. I now construct what’s in my CLI folder that I named after my cli project ‘great_houses_cli’. This is where we make our bread and butter. Here we will have our CLI Class, API Class, and my Model Object Class (House Class). Quick review: CLI Class is responsible for communicating with the user. API Class is responsible for making a call to api, for getting the necessary data, and turning it into Ruby Objects(Object Orientation). The Model Object Class is a factory of how each object will look like, and design what behaviors and properties each object will have. It keeps track of all its instances and is responsible for the entire class as well. I also have my find method in my house class that will, later on, be utilized in our CLI Class.

def self.find_house(house_name)  self.all.find {|house| house.name == house_name}end

In the above code, this method accepts the house name and finds the object with that name. This method is again used in CLI class in my house_selection method. This is the reason why my user is able to see the list of houses from my API data.

Next, I worked on my CLI Class that consists of my start, greeting, user_input, house_list, house_selection, house_details, menu, goodbye, and an invalid method. As mentioned above CLI class is responsible for interacting with my user which required all these methods to be possible to interact back and forth.

Lastly, I finish up my API class. We need to create actual ruby objects out of the API data, and that is the reason why we created the Model Object(House) Class. An endpoint is required for the data we are accessing. In this case, my endpoint is https://api.got.show/api/show/house.

class API  def self.get_data   response = RestClient.get('https://api.got.show/api/show/houses')   houses_array = JSON.parse(response)   houses_array.each do |house|     if house["name"].start_with?("House")         House.new(house)     end   end  endend

Then updated my ‘start’ method in CLI Class with this API call. We want to make this call when the user initiates my cli to begin loading up information, which is why we put it in the first method.

.get_data

Our .get_data method is responsible for getting a response from that endpoint. This line gives us the response object that we need to parse through JSON.parse. These are accessible through our gems ‘json’ and ‘rest-client’ that I added in our gemfile.

HURDLES I came across.

The first thing I noticed once my cli was executable, and I was able to play around with it and pick and choose a house I wanted more information on, was that some of the attributes were returning with brackets and some are empty. It would return my attribute names, but some of them were empty for certain houses. For example, House Selmy did not have ‘words’ unlike House Stark would have “Winter is coming”. Okay, how do I want to go about it, did I want to leave it as is, or do I NOT want to return that attribute. I decided the latter.

To change it to return how I wanted it, I needed to decide first where I want this change to happen. I had a feeling it would be where I interpolate these attributes, but I wanted to make sure and checked with my instructor. She clarified that it would be there. I added this line of code after my strings.

if house.words != ""

In the above code I’m saying that if house.words does NOT equal to an empty string then execute as in return the words.

As for the brackets returning along with my data, it was an indication that the data was in an array, and double checked by utilize ‘binding.pry’.

" #{house.allegiance.join(", ")}" if house.allegiance.join != ""

Once I distinguished it was, I had to join my elements into a string first, passed in an argument of (“, “) making sure elements are spaced out properly. Then again added my conditional method. To accomplish my goal of not return any empty attribute as well as not show the brackets when it does have something to return.

Last but not least, going through 170+ objects of houses I realize some are not houses, and none of them started with the word “House”. My thought process once again was “where do I fix this?”. In my API class, where I iterate over each of these objects to return to my user.

My initial code:

def self.get_data   response = RestClient.get('https://api.got.show/api/show/houses')   houses_array = JSON.parse(response)   houses_array.each do |house|       House.new(house)   endend

end code:

   houses_array.each do |house|       if house["name"].start_with?("House")          House.new(house)       end   end

In the above code, I added a conditional that if a house START WITH the word “House” then return and execute the next code House.new(house) which is instantiating a new object with the attributes I gave it. Remember my Class has all the details and attributes.

My end result example after fixing everything:

Name: House StarkRegion: The NorthSeat: WinterfellAllegiance: House Targaryen, House Baratheon of King's LandingSigil: A grey direwolf on a white fieldWords: "Winter Is Coming"

Favorite Thing I Learned

Was that I had to know what format my data was in and how to access it. My API was javascript format, and I had learned that I needed to access it in this manner vs to trying to access it like a regular Ruby hash.

house["name"]

Disclaimer

If you hadn’t notice I’ll point it out, another hurdle I came across was having to change my API end point. The one I used is not included in the public API link I provided. I decided I didn’t want to work with the original API(from public API link) I chose for the reasons of not having the data I wanted. I realized this once my cli was up and running and was not returning a whole lot of information. I freaked out a bit, and started thinking about changing my whole project. But with rigorous research and patience I found ANOTHER Game Of Thrones CLI that contains data of its houses and more! So pro-tip for anyone that will be needing an API for your CLI project, make sure you take your time to look through the API and make sure it is something that you see yourself working with, and if not, you realize it later on? That’s alright too, you gain a learning experience and that’s the best experience one can ask for when programming. So shoutout to the creators of this wonderful API(find link below), thanks for reading!

Repository:

Video:

https://youtu.be/bIeXjaLHk9c

Sources:

--

--