Making with Code

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
๐Ÿ’ป Get the necessary packages
poetry update
๐Ÿ’ป Enter the Poetry shell
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 the database in the DB Browser:
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.

๐Ÿ’ป Try changing or adding rows.

๐Ÿ’ป 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 the new_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 as True

๐Ÿ“– 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
        },
    ]
}


๐Ÿ’ป 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 the HTTPie 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 many Fortunes.