Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

c15 Accelerate - Regina Tam, Lilia Paz, Trish Griego #9

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,34 @@
migrate = Migrate()
load_dotenv()


def create_app():
def create_app(test_config=None):
app = Flask(__name__)
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get(
if test_config is None:
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get(
"SQLALCHEMY_DATABASE_URI")
else:
app.config["TESTING"] = True
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get(
"SQLALCHEMY_TEST_DATABASE_URI")

# Import models here for Alembic setup
# from app.models.ExampleModel import ExampleModel
from app.models.board import Board
from app.models.card import Card

db.init_app(app)
migrate.init_app(app, db)

# Register Blueprints here
# from .routes import example_bp
from .routes import boards_bp
from .routes import cards_bp

# app.register_blueprint(example_bp)
app.register_blueprint(boards_bp)
app.register_blueprint(cards_bp)

CORS(app)
return app
9 changes: 9 additions & 0 deletions app/models/board.py
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
from sqlalchemy.orm import backref
from app import db

class Board(db.Model):
board_id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String)
owner = db.Column(db.String)
cards = db.relationship("Card", backref="board", lazy=True)
# not sure if we actually need cards here.
# sort of like we had tasks.
6 changes: 6 additions & 0 deletions app/models/card.py
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
from app import db

class Card(db.Model):
card_id = db.Column(db.Integer, primary_key=True)
message = db.Column(db.String)
likes_count = db.Column(db.Integer)
board_id = db.Column(db.Integer, db.ForeignKey("board.board_id"))
218 changes: 217 additions & 1 deletion app/routes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,220 @@
from flask import Blueprint, request, jsonify, make_response
from app import db
from app.models.board import Board
from app.models.card import Card
from dotenv import load_dotenv
import requests

# example_bp = Blueprint('example_bp', __name__)
load_dotenv()
boards_bp = Blueprint("boards", __name__, url_prefix="/boards")
cards_bp = Blueprint("cards", __name__, url_prefix="/cards")

# ----------------- Board Endpoints ----------------- #
# Get all boards --> done
# Create a board --> done
@boards_bp.route("", methods=["GET", "POST"])
def handle_boards():

if request.method == "GET":
boards = Board.query.all()
boards_response = []

for board in boards:
boards_response.append({
"board_id": board.board_id,
"title": board.title,
"owner": board.owner
})

return make_response(jsonify(boards_response), 200)

elif request.method == "POST":
request_body = request.get_json()
if "title" not in request_body:
return {
"details": f"Invalid data. Must include title."
}, 400
if "owner" not in request_body:
return {
"details": f"Invalid data. Must include owner."
}, 400

new_board = Board(
title=request_body["title"],
owner=request_body["owner"]
)
db.session.add(new_board)
db.session.commit()

return make_response({
"board": {
"id": new_board.board_id,
"title": new_board.title,
"owner": new_board.owner
}
}, 201)

# Delete a board by ID --> done
# Get a board by ID --> done
# Edit a board by ID --> done
@boards_bp.route("/<board_id>", methods=["DELETE", "GET", "PUT"])
def handle_board(board_id):
board = Board.query.get(board_id)
if board is None:
return make_response(f"Board {board_id} not found. ", 404)

if request.method == "DELETE":
db.session.delete(board)
db.session.commit()

return make_response(
{
"details":
f"Board: {board.board_id} with title: {board.title}. Successfully deleted"
}
)

elif request.method == "GET":
return {
"id": board.board_id,
"title": board.title,
"owner": board.owner
}

elif request.method == "PUT":
form_data = request.get_json()
board.title = form_data["title"]
board.owner = form_data["owner"]

db.session.commit()

return make_response({
"board": {
"id": board.board_id,
"title": board.title,
"owner": board.owner,
}
})


# ----------------- Card Endpoints ----------------- #
# Getting cards by board_id --> done
# Creating a card & associating it with a specific board --> done
@boards_bp.route("/<board_id>/cards", methods=["GET", "POST"])
def handle_board_cards(board_id):

if request.method == "POST":
board = Board.query.get(board_id)

if not board:
return make_response({
f"Board #{board_id} not found."
}, 404)

request_body = request.get_json()
if "message" not in request_body:
return {
"details": f"Invalid, must include message."
}

new_card = Card(
message=request_body["message"],
likes_count=0,
board_id=board.board_id
)
db.session.add(new_card)
db.session.commit()

return make_response({
"card": {
"id": new_card.card_id,
"message": new_card.message,
"likes_count": new_card.likes_count,
"board_id": new_card.board_id
}
}, 201)

elif request.method == "GET":
board = Board.query.get(board_id)
if not board:
return make_response(f"Board {board_id} not found", 404)
cards = board.cards

list_of_cards = []

for card in cards:
individual_card = {
"id": card.card_id,
"board_id": board.board_id,
"message": card.message,
"likes_count": card.likes_count
}
list_of_cards.append(individual_card)
return make_response({
"id": board.board_id,
"title": board.title,
"owner": board.owner,
"cards": list_of_cards
})

# Delete a card by ID --> done
# Get card by ID --> done
# Edit card by ID --> done
@cards_bp.route("/<card_id>", methods=["DELETE", "GET", "PUT"])
def handle_card(card_id):
card = Card.query.get(card_id)

if card is None:
return make_response(f"Card #{card_id} not found.", 404)

if request.method == "DELETE":
db.session.delete(card)
db.session.commit()

return make_response(
{
"details": f"Card at card_id: {card.card_id}. Successfully deleted"
}
)

elif request.method == "GET":
return make_response({
"id": card.card_id,
"message": card.message,
"likes_count": card.likes_count,
"board_id": card.board_id
})

elif request.method == "PUT":
form_data = request.get_json()
card.message = form_data["message"]

db.session.commit()

return make_response({
"card": {
"id": card.card_id,
"message": card.message,
"likes_count": card.likes_count,
"board_id": card.board_id
}
})

# ----------------- Increase Card Likes ----------------- #
@cards_bp.route("/<card_id>/like", methods=["PUT"])
def handle_likes(card_id):
card = Card.query.get(card_id)

if card is None:
return make_response({
f"Card #{card_id} not found."
}, 404)

if request.method == "PUT":

card.likes_count += 1
db.session.commit()

return make_response(
{"likes_count": card.likes_count}
), 200
93 changes: 93 additions & 0 deletions crud_plans.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# CRUD Operations for the Inspo Board backend API
- You will need to replace the <board_id>s and <card_ids>s for your own usecases.

# Handling Boards
### Post --> Create a new Board
- `/boards`
- `https://inspo--board.herokuapp.com/boards`

Example Payload body:
```json
{
"title": "Arizona",
"owner": "TrishTheDish"
}
```
Endpoint will not let you create a board without a title or owner. It will give you an error message alerting you to this fact.

***
### PUT --> Edit a board by ID
- `/boards/<board_id>`
- `https://inspo--board.herokuapp.com/boards/2`

Example Payload body:
```json
{
"owner": "Rudy G",
"title": "Lumber is a board."
}
```
Endpoint will not let you edit a board that doesn't exist. Will give you helpful message if the board doesn't exist.

***
### DEL --> Delete a board by ID
- `/boards/<board_id>`
- `https://inspo--board.herokuapp.com/boards/3`

Endpoint will not let you delete a board that doesn't exist. Will give you a helpful message if board doesn't exist.

***
### GET --> Get a board by ID
- `/boards/<board_id>`
- `https://inspo--board.herokuapp.com/boards/2`

Endpoint will not let you get board that doesn't exist. Will give you helpful message if board doesn't exist.

***
### GET --> Get all The Boards if any exist
- `/boards`
- `https://inspo--board.herokuapp.com/boards`

If no boards exist then it will return an empty array.


# Handling Cards
### Post --> creating new card for a particular board.
- `boards/<board_id>/cards`
- `https://inspo--board.herokuapp.com/boards/2/cards`

Example Payload body:
```json
{
"message": "here is a lovely quote for you to post"
}
```
***
### GET --> Get All Cards associated with a particular board.
- `/boards/<board_id>/cards`
- `https://inspo--board.herokuapp.com/boards/2/cards`

***
### Get --> Get card by ID
- `/cards/<card_id>`
- `https://inspo--board.herokuapp.com/cards/9`
***

### DEL --> Delete a card ny ID
- `/cards/<card_id>`
- `https://inspo--board.herokuapp.com/cards/9`
***
### PUT --> Edit card by ID
- `/cards/<card_id>`
- `http://127.0.0.1:5000/cards/8`

```json
{
"message": "editing it one more time"
}
```

# Handle Likes
### Put --> Increase Likes Count by 1
- `/cards/<card_id>/like`
- `https://inspo--board.herokuapp.com/cards/9/like`
1 change: 1 addition & 0 deletions migrations/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generic single-database configuration.
Loading