Client
In this lab we will create a Client in the form of a Command Line Interface(CLI) for the Riddle server. We will use the Requests
library to send and recieve HTTP requests.To learn more about the Requests
library, checkout its documentation
[0] What is a client?
Since the riddle server is an API with no user interface, we end up writing a lot of HTTP requests into the Terminal to use it. What if we had a program which took care of making these requests for us? A program like this is called a client.
Any app which uses the Internet is a client.
The client, or app, is constantly making HTTP requests to a server to send and receive information.
[1] Set Up
๐ป Go to the unit folder, clone the riddler server lab, and cd into the repo.cd ~/desktop/making_with_code/cs10/unit00_networking/
git clone https://github.com/the-isf-academy/lab_client_YOURGITHUBUSERNAME
cd lab_client_YOURGITHUBUSERNAME
poetry install
poetry shell
[2] Try the Client
We are going to create a Terminal interface for the riddler server. This will allow users to easily interact with the server without needing to explicitly make a GET
or POST
request.
python client.py
-----------------------------------
---- Welcome to the Riddler ----
-----------------------------------
> View All Riddles
View One Riddle
Quit
๐ป Open the client.py file in atom and take a look inside:
atom client.py
[RiddleClient]
The RiddleClient
has the following properties:
Property | Description |
---|---|
riddle_server | stores the url of the riddle server |
menu_options | stores a list of the menu options |
And the following methods:
Method | Description |
---|---|
menu() | allows user to pick a menu option and returns the option as a string |
run() | runs the client and controls the logic of the client - all user input is taken here |
view_all_riddles() | GETS all of the riddles and prints them as a bulleted list |
view_one_riddle(user_chosen_id) | GETS one riddle with the requested ID |
[run()]
๐
Let’s start by taking a look at the method run()
. This method controls the logic of the client. It also is the only method in the client that takes user input.
|
|
lines 4-6:
prints a starting message to the userline 8:
client_running
is the variable that keeps track if the user is still using the clientline 11:
stores the user’s choice when they select a menu optionlines 13, 18, 25:
control the logic for each menu option
[view_all_riddles()]
๐
Now let’s look at the working method view_all_riddles()
. This method sends an HTTP GET request to the Riddle server endpoint riddles/all
and prints all of the riddles in a bulleted list.
|
|
line 5:
stores the full URL address of where to get all of the riddles. It uses theriddle_server
property of the client class as the base address and adds the endpoint to the end of it.line 7:
sends an HTTP GET request to the server and stores the response.lines 9-13:
If the HTTP request was sucessful, it prints each riddle one at a time in a nicely formatted bulleted list.line 10:
converts the response from the server into JSON.
line 14-17
: If the HTTP request was unsuccessful, it prints the error status code and the error message.
[view_one_riddle()]
๐
Finally take a look at the method view_one_riddle()
. This method sends an HTTP GET request to the Riddle server endpoint riddles/one
and print a single riddle with the requested ID.
|
|
line 5:
stores the full URL address of where to get one riddle.lines 7-9:
stores the payload in a dictionary.line 11:
sends an HTTP GET request with the payload to the server and stores the response.lines 13-17:
If the HTTP request was sucessful, it prints a single riddle with each of its properties in a bulleted list.line 14:
converts the response from the server into JSON.
line 19-22
: If the HTTP request was unsuccessful, it prints the error status code and the error message.
[3] Extend the Client
Your job is to add 2 functionalites to the RiddleClient.py
. This will require you to edit a property, edit a method, and add methods to RiddleClient
.
new riddle
- should allow the user to input a riddle question and answer, send a post request, and print the newly added riddleguess riddle
- should allow the user to guess a specific riddle, send a post request, and print a message telling the user is their guess was correct or incorrect
[new riddle]
This will require you to edit:
menu
run()
Write a method new_riddle()
:
- take two parameters:
user_question
anduser_answer
- send an HTTP POST request with the user’s question and answer to the server’s endpoint
riddles/new
- print the newly added riddle
๐ Take a look at the pseudocode for this funcitonality.
0) edit the `menu` property
1) edit the `run()` method
- add a conditional statement
- print a header to tell the user which menu option they are in
- store the user input for the riddle question and answer
- call the `new_riddle()` method with the stored user input as parameters
2) write the `new_riddle()` method
- store the new riddle server address
- store the payload in a dictionary
- make the http post request and store the response
- if the response was successful
- convert the response to JSON
- print the newly added riddle in a nice format
- else if the response was incorrect, tell the user
๐ป Translate the pseudocode into Python code to implement the new riddle functionality into the client. The client interaction should look something like this:
[New Riddle]
Enter a Riddle question: What kind of room has no doors or windows?
Enter the answer: A mushroom
Riddle Successfully Added!
โข answer: A mushroom
โข correct: 0
โข guesses: 0
โข id: 37
โข question: What kind of room has no doors or windows?
[guess riddle]
This will require you to edit:
menu
run()
Write a method guess_riddle()
:
- take two parameters:
user_chosen_id
anduser_guess
- send an HTTP POST request with the user’s guess and corresponding riddle id to the server
- print if the guess was correct or incorrect.
โ๏ธ Write pseudocode for
guess_riddle()
keeping the following in mind:
- Do you need anything from the user?
- What endpoint do you need?
- Does the endpoint require a payload?
- How do you nicely format a dictionary to print to the user?
๐ป Code this functionality to allow the user to guess a riddle. Reference your pseudocode to consider how to implement guessing a riddle. Be sure to look at the existing code for a starting off point.
The client interaction should look something like this:
[Guess a Riddle]
Enter Riddle ID: 10
โข correct: 0
โข guesses: 2
โข id: 10
โข question: What is born with 4 legs, loses 2 legs, and has 3 before it dies?
Enter your guess: Dragon
Incorrect!
[4] Deliverables
โกโจ Once you've successfully completed the client:
โ๏ธ Fill out this Google form
๐ป Push your code to Github.
[5] Extension
[Gamify]
Currently, the client simply takes care of the HTTP requests in a nicely formatted view. But, let’s make it more fun and turn it into a game!
๐ป Extend the functionality of the client and allow the user to play a guessing game.The game should:
- display each riddle on the riddle server
- allow the user to guess each riddle
Gameplay should look something like this:
-----------------------------------
---- Welcome to the Riddler ----
-----------------------------------
[Riddler Game]
Question: Do you exist?
Enter your guess: no
Correct!
Question: What can fill a room but takes up no space?
Enter your guess: silence
Incorrect!
Question: What cups do not hold water?
Enter your guess:
Potential further extension features:
- keep score of how many riddles the user guesses correctly
- display the current score after each riddle is guessed
- randomly display each riddle
[Magic 8]
In this extension