Fortune Server #
In this lab we are going to delve further into Banjo by focusing on models.py
and error handling in views.py
.
๐ Open the Banjo documentation: the-isf-academy.github.io/banjo_docs/
[0] Set Up #
For this lab, we need to download software to view the database in a nicely formatted chart.
๐ป Download dbsqlite onto your computer: https://sqlitebrowser.org/dl/
You are each able to run a locally hosted fortune server on your laptop using Banjo.
๐ป Now, let's clone the repository
in your cs10\unit00_networking
folder. Be sure to change yourgithubusername
to your actual Github username.
cd ~/desktop/making_with_code/unit04_networking/
git clone https://github.com/the-isf-academy/lab_fortune_yourgithubusername
cd lab_fortune_yourgithubusername
poetry update
poetry shell
[1] Running the Fortune Server #
๐ป Start your local server.banjo --debug
๐ป Test the server using HTTPie
:
127.0.0.1:5000/fortune/all
[2] Models.py #
Banjo has 4 basic options for Field types
StringField
IntegerField
FloatField
BooleanField
๐ Let’s start by looking at the model for Fortune
.
from banjo.models import Model, StringField, IntegerField, BooleanField
class Fortune(Model):
statement = StringField()
category = StringField()
likes = IntegerField()
archive = BooleanField()
Viewing the Database #
You have just downloaded a simple server that hosts Fortunes
onto your laptop. Let’s start by looking at the its database.
open database.sqlite
๐ป Select
Browse Data
Here you will see all of the riddles that are in your locally hosted server.
This database file gets updated each time make a POST
request.
๐ป
Be sure to save command + s
the database to ensure the changes are saved.
๐ป See you changes by sending a GET
request to:
127.0.0.1:5000/fortune/all
In this lab you will edit models.py
and views.py
.
๐ป Start by opening up the primary folder:
/app
code app
๐ป
Open the models.py
file. You will write two methods to update the likes
and statement
fields.
Update the likes
#
๐ป
Write the increase_likes()
method.
- increase
likes
by 1 - save the object
Example usage:
one_fortune = Fortune.objects.get(id=1])
one_fortune.increase_likes()
Update the statement
#
๐ป
Write the change_statement()
method.
- it takes
new_statement
as a parameter - it changes the
statement
field to thenew_statement
- reset the
likes
to 0 - save the object
Example usage:
one_fortune = Fortune.objects.get(id=1])
one_fortune.change_statement('You will win a tesla')
[3] Views.py #
๐ป
Open the views.py
file. This server has 2 endpoints:
/new
/all
It is up to you to write /likes
, /change_statement
, and /search
/like #
๐ป
Write the fortune/like
endpoint.
- HTTP method:
post
- Payload/args:
id
- if the fortune exists
- increase the likes
- return the fortune with the
id
,statement
,likes
,category
- else
- a helpful error message
โ CHECKPOINT:๐ป Test the endpoint in the
HTTPie desktop app
http://127.0.0.1:8000/fortune/like id=1
โ๏ธ It should return
json
like:{ "fortune": { "id": 1, "statement": "You will win a tesla", "likes": 10, "is_happy": "true" } }
/change_statement #
๐ป
Write the fortune/change_statement
endpoint.
- HTTP method:
post
- Payload/args:
id
,new_statement
- if the fortune exists
- change the statement
- return the fortune with the
id
,statement
,likes
,category
- else
- a helpful error message
โ CHECKPOINT:๐ป Test the endpoint in the
HTTPie desktop app
http://127.0.0.1:8000/fortune/change_statement id=1 new_statement="You will win a new iPhone"
โ๏ธ It should return
json
like:{ "fortune": { "id": 1, "statement": "You will win a new iPhone", "likes": 0, "is_happy": "true" } }
/all/happy #
๐ป
Write the fortune/all/happy
endpoint.
- HTTP method:
get
- Payload/args: none
- It should return all of the fortunes with
is_happy
set asTrue
๐ Check the banjo documentation to find the best way to query the database: the-isf-academy.github.io/banjo_docs/
๐ค Consider:
- Which existing endpoint is similar?
- How should you format the json that you return?
- What should you return to the user if no fortunes match their search term?
โ CHECKPOINT:๐ป Test the endpoint in the
HTTPie desktop app
http://127.0.0.1:8000/fortune/all/happy
โ๏ธ It should return
json
like:{ "fortunes": [ { "id": 1, "statement": "A surprise pizza is coming", "likes": 0, "is_happy": true }, { "id": 2, "statement": "A random act of kindness will lead to a new friendship", "likes": 0, "is_happy": true }, ] }
/search #
๐ป
Write the fortune/search
endpoint.
- HTTP method:
get
- Payload/args:
keyword
- It should return all of the fortunes with the keyword.
- If no fortunes exist, provide a helpful error message
๐ Check the banjo documentation to find the best way to query the database: the-isf-academy.github.io/banjo_docs/
๐ค Consider:
- Which existing endpoint is similar?
- How should you format the json that you return?
- What should you return to the user if no fortunes match their search term?
โ CHECKPOINT:๐ป Test the
fortune/like
endpoint in theHTTPie desktop app
http://127.0.0.1:8000/fortune/search keyword="surprise"
โ๏ธ It should return
json
like:{ "fortunes": [ { "id": 1, "statement": "A surprise pizza is coming", "likes": 0, "is_happy": true }, { "id": 6, "statement": "A surprise typhoon day is in your future", "likes": 0, "is_happy": true } ] }
[6] Deliverables #
โกโจOnce you’ve successfully completed the worksheet be sure to fill out this Google form.
๐ป Push your work to Github:
- git status
- git add -A
- git status
- git commit -m “describe your code and your process here”
be sure to customize this message, do not copy and paste this line
- git push
[7] Extensions #
Archive #
Currently there is no feature to delete a fortune. It can be risky to permanently delete an item from the database, so instead let’s utilize the archive feature.
๐ป Write a method change_archive()
that sets the archive
field to False
.
๐ป Write a new route /change_archive
to change the archive
field of a fortuen with a given id
.
๐ป Change your exisitng routes (/all
, /search
) to only return fortunes with arhive
set to True
.
Calculate Popularity % #
๐ป Create a new field popularity_percentage
to store a for each Fortune
. It should be a FloatField
. It is up to you to decide how to calculate this percentage. You may want to:
- add additional fields
- loop through all of the database
Foreign Key #
Banjo has the ability to have relational databases.
from banjo.models import Model, StringField, IntegerField, ForeignKey, BooleanField, FloatField
class Artist(Model):
name = StringField()
class Song(Model):
name = StringField()
artist = ForeignKey(Artist)
As Banjo is a wrapper over Django, it works just as the Django documentation states HERE.
In the example code above, a Artist can be associated with many Song objects, but a Song object can only have one Artist object.
๐ป Try to incorporate a many-to-one relationship in models.py
. An example:
- each
Person
could have manyFortune
s.