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

Tigers- Lindsey, Rose, QP, Tiff #26

Open
wants to merge 47 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
2c9ef6f
Adds Board and Card Models
Lindseymarcea Jan 3, 2023
3ecd831
Created Board Blueprint
Lindseymarcea Jan 3, 2023
3061e5e
Creat board route, added from_dict & to_dict methods
Lindseymarcea Jan 3, 2023
beb3fd6
completed Card to_dict and from_dict functions
Jan 3, 2023
9250a95
updated route namesto register blueprints in app/__init__.py
Jan 3, 2023
54ddcb8
added create card and get all card routes to board.py
Jan 4, 2023
e9bb874
Merge pull request #1 from Lindseymarcea/card
Anaiq Jan 4, 2023
0c3153a
Working on Get all, and get one routes
Lindseymarcea Jan 4, 2023
5a984ff
Resolved Merge conflicts
Lindseymarcea Jan 4, 2023
32cfa75
Editing get all boards
Lindseymarcea Jan 4, 2023
3e00ec6
updated board model and routes
Jan 4, 2023
d42fcf0
merge conflict resolved
Jan 4, 2023
54a650b
add () to commit to db
Jan 4, 2023
dc40f6f
adding Tiff's migrations
tiffanyt86 Jan 4, 2023
572b9f6
Merge branch 'main' of https://github.com/Lindseymarcea/back-end-insp…
tiffanyt86 Jan 4, 2023
d379acd
Created delete and update requests
Lindseymarcea Jan 4, 2023
3e8b00e
completed delete and update card routes, response body in progress
Jan 4, 2023
fc4e267
Merge pull request #2 from Lindseymarcea/card2
Anaiq Jan 4, 2023
daf15e3
completed response budy for update route. all routes passing postman …
Jan 4, 2023
313be7f
updated put response for card
Jan 5, 2023
80af8aa
Merge branch 'main' of https://github.com/Lindseymarcea/back-end-insp…
tiffanyt86 Jan 6, 2023
bec664f
added test config to __init__.py
Jan 6, 2023
6e4245d
added edited update adn delete routes to card.py and edited return s…
Jan 6, 2023
d963b90
added model test file, added imports to test_routes, updated confest.…
Jan 15, 2023
9e85bca
added fixtures to conftest.py one and four boards, one card, created …
Jan 16, 2023
d22b944
added card fixture to conftest, added no_saved_cards and get_one_card…
Jan 16, 2023
b4dea14
able to fix bug for test_get_cards_from_one_board_no_saved_cards and …
Jan 17, 2023
5581c86
fixed typo in test_routes.py
Jan 17, 2023
ae686ef
Merge branch 'main' of https://github.com/Lindseymarcea/back-end-insp…
tiffanyt86 Jan 17, 2023
9025642
Merge pull request #3 from Lindseymarcea/tests
Anaiq Jan 17, 2023
e24c025
adding create board and delete board
Jan 17, 2023
1e84dd0
completed CRUD tests for board and card, all tests passing
Jan 17, 2023
9779028
Merge pull request #4 from Lindseymarcea/tests
Anaiq Jan 17, 2023
76061ac
Get boards alphabetically made
Lindseymarcea Jan 17, 2023
65ebe95
other changes
Lindseymarcea Jan 17, 2023
ddeeac0
minor changes
Lindseymarcea Jan 18, 2023
ef51e24
Co-authored-by: QP <[email protected]>
Lindseymarcea Jan 18, 2023
2110d9a
Merge branch 'main' of https://github.com/Lindseymarcea/back-end-insp…
tiffanyt86 Jan 18, 2023
610be35
Add Procfile
Lindseymarcea Jan 18, 2023
e7a9517
update Board.py to return cards in response object
tiffanyt86 Jan 18, 2023
02e256e
Merge branch 'main' of https://github.com/Lindseymarcea/back-end-insp…
Lindseymarcea Jan 18, 2023
966fc88
removed message key from update_card function
tiffanyt86 Jan 18, 2023
2d76500
Merge branch 'main' of https://github.com/Lindseymarcea/back-end-insp…
tiffanyt86 Jan 18, 2023
b2942b0
updated fixtures and tests to include key for cards list for boardobj…
Jan 19, 2023
42a8740
Moved Procfile
Lindseymarcea Jan 19, 2023
6d2740a
Minor changes
Lindseymarcea Jan 19, 2023
e143ddb
Merge branch 'main' of https://github.com/Lindseymarcea/back-end-insp…
Lindseymarcea Jan 19, 2023
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
24 changes: 17 additions & 7 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,32 @@
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(
"SQLALCHEMY_DATABASE_URI")
if not test_config:
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.card import Card
from app.models.board import Board

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

# Register Blueprints here
# from .routes import example_bp
# app.register_blueprint(example_bp)
from .board_routes import board_bp
app.register_blueprint(board_bp)

from .card_routes import card_bp
app.register_blueprint(card_bp)

CORS(app)
return app
116 changes: 116 additions & 0 deletions app/board_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
from flask import Blueprint, request, jsonify, make_response, abort
from app import db
from app.models.board import Board
from app.models.card import Card
import os, requests

# creating blueprint
board_bp = Blueprint("Board", __name__, url_prefix="/boards")

#VALIDATE MODEL
def validate_model(class_obj,id):
try:
id = int(id)
except:
abort(make_response({"message":f"{id} is an invalid id"}, 400))
query_result = class_obj.query.get(id)
if not query_result:
abort(make_response({"message":f"{id} not found"}, 404))

return query_result

# CREATE BOARD/POST
@board_bp.route("", methods=["POST"])
def create_board():
request_body = request.get_json()

if "title" not in request_body or "owner" not in request_body:
return make_response({"Details": "Missing title or owner"}, 400)

new_board = Board.from_dict(request_body)

db.session.add(new_board)
db.session.commit()
response_body = new_board.to_dict()

return make_response(response_body, 201)

# send a request to create a new card and connect it to a board already found in the database
@board_bp.route("/<board_id>/cards", methods=["POST"])
def create_card_associated_with_board(board_id):
board = validate_model(Board, board_id)

request_body = request.get_json()
new_card = Card(
board=board,
message=request_body["message"],
likes_count=request_body["likes_count"]
)

db.session.add(new_card)
db.session.commit()

return new_card.to_dict(), 201
# return make_response(jsonify(f"Card {new_card.message} on {new_card.board.title} successfully created"), new_card.to_dict(), 201)

#send a request to read all cards on a particular board in the database.
@board_bp.route("/<board_id>/cards", methods=["GET"])
def read_all_cards_from_board(board_id):
board = validate_model(Board, board_id)


cards_response = []
for card in board.cards:
cards_response.append(card.to_dict())
return jsonify(cards_response)

# READ ALL BOARDS/ GET
@board_bp.route("", methods=["GET"])
def get_all_boards():
title_sort_query = request.args.get("sort")
if title_sort_query == "asc":
boards = Board.query.order_by(Board.title.asc())
elif title_sort_query == "desc":
boards = Board.query.order_by(Board.title.desc())
else:
boards = Board.query.all()

response = []
for board in boards:
response.append(board.to_dict())
return jsonify(response), 200
# return response.to_dict()

# READ ONE BOARD/ GET
@board_bp.route("/<board_id>", methods=["GET"])
def get_one_board(board_id):

board = validate_model(Board, board_id)
# if board.card_id is None:
# return {"board": board.to_dict()}
# else:
return board.to_dict()

# UPDATE BOARD/ PUT
@board_bp.route("/<board_id>", methods=["PUT"])
def update_board(board_id):
board = validate_model(Board, board_id)
request_body = request.get_json()
board.title = request_body["title"]
board.owner = request_body["owner"]

db.session.commit()
response_body = board.to_dict()
return make_response(response_body, 200)

# DELETE BOARD/ DELETE
@board_bp.route("/<board_id>", methods=["DELETE"])
def delete_one_board(board_id):

board = validate_model(Board, board_id)

db.session.delete(board)
db.session.commit()

return {
"details": f'Board {board_id} successfully deleted'}
42 changes: 42 additions & 0 deletions app/card_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from flask import Blueprint, request, jsonify, make_response, abort
from app import db
from app.models.card import Card
from app.models.board import Board
import os, requests
from app.board_routes import validate_model

# Card
# CREATE a new card to a board (in board_routes)
# READ all cards belonging to a board (in board_routes)
# UPDATE ‘+1’s for a card
# DELETE a card


# creating blueprint
card_bp = Blueprint("Card", __name__, url_prefix="/cards")

#send a request to read all cards on a particular board in the database.
@card_bp.route("/<card_id>/like", methods=["PUT"])
def update_card(card_id):
card = validate_model(Card, card_id)

request_body = request.get_json()

card.likes_count = request_body["likes_count"] + 1

db.session.commit()

return card.to_dict(), 200
# return make_response(jsonify(f"Card {card.card_id} on {board.title} successfully updated"), 200)


# send a request to delete a card from a particular board in the database
@card_bp.route("/<card_id>", methods=["DELETE"])
def delete_card(card_id):
card = validate_model(Card, card_id)

db.session.delete(card)
db.session.commit()

return {"details": f'Card {card.card_id} successfully deleted")'}
# return make_response(jsonify(f"Card {card.card_id} on {board.title} successfully deleted"), 200)
39 changes: 39 additions & 0 deletions app/models/board.py
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
from app import db
from flask import jsonify

# from app.models.card import Card

#ONE to many relationship
class Board(db.Model):
board_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String)
owner = db.Column(db.String)
cards = db.relationship("Card", back_populates="board", lazy=True)


def to_dict(self):

cards_list = []
for card in self.cards:
cards_list.append(card.to_dict())

return {
"title": self.title,
"owner": self.owner,
"id": self.board_id,
"cards": cards_list
}









@classmethod
def from_dict(cls, request_body):
return Board(
title=request_body["title"],
owner=request_body["owner"],
)
27 changes: 27 additions & 0 deletions app/models/card.py
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
from app import db
# from app.models.board import Board

# one to MANY relationship
class Card(db.Model):
card_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
message = db.Column(db.String)
likes_count = db.Column(db.Integer)
board_id = db.Column(db.Integer, db.ForeignKey("board.board_id"))
board = db.relationship("Board", back_populates="cards")


def to_dict(self):
card_as_dict = {}
card_as_dict["id"] = self.card_id
card_as_dict["message"] = self.message
card_as_dict["likes_count"] = self.likes_count
card_as_dict["board_id"] = self.board_id

return card_as_dict

@classmethod
def from_dict(cls, request_body,):
return Card(
message=request_body["message"],
likes_count=request_body["likes_count"]
)

4 changes: 0 additions & 4 deletions app/routes.py

This file was deleted.

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.
45 changes: 45 additions & 0 deletions migrations/alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# A generic, single database configuration.

[alembic]
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s

# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false


# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
Loading