Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ venv.bak/
# mkdocs documentation
/site

play.py
# mypy
.mypy_cache/
.dmypy.json
Expand Down
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: gunicorn 'app:create_app()'
11 changes: 9 additions & 2 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,19 @@ def create_app(test_config=None):
"SQLALCHEMY_TEST_DATABASE_URI")

# Import models here for Alembic setup
from app.models.task import Task
# from app.models.task import Task
# from app.models.goal import Goal
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can remove these comments

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got internet again. Removed lines 26 and 27

from app.models.task import Task
from app.models.goal import Goal

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

# Register Blueprints here
from .routes import tasks_bp
app.register_blueprint(tasks_bp)

from .goal_routes import goals_bp
app.register_blueprint(goals_bp)

return app
173 changes: 173 additions & 0 deletions app/goal_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
from app.models.goal import Goal
from app.models.task import Task
from flask import Blueprint, jsonify, abort, make_response,request
from app import db
from datetime import datetime, date, time, timezone
import requests

goals_bp = Blueprint("goals_bp", __name__, url_prefix="/goals")

# Helper Function
def validate_goal(id):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like that you have specific error messages so the user knows exactly wants going on!

try:
goal_id = int(id)
except ValueError:
abort(make_response(jsonify(dict(details=f"Invalid id {goal_id}")), 400))


goal = Goal.query.get(id)
if goal:
return goal

abort(make_response(jsonify(dict(details=f"No goal with id {goal_id} found")), 404))

# CREATE NEW TASK
@goals_bp.route("", methods=[ "POST"])
def create_goal():
request_body = request.get_json()

if request_body == {}:

response_body = {
"details": "Invalid data"
}, 400

return response_body


new_goal = Goal(
title=request_body["title"])


db.session.add(new_goal)
db.session.commit()

response_body = { "goal":
{
"id": new_goal.goal_id,
"title": new_goal.title
}
}, 201
Comment on lines +45 to +50
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can you create an instance method or helper function so you don't have to repeat this code ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can create an instance method but am unclear as to how to incorporate it in this function


return response_body


@goals_bp.route("/<goal_id>", methods=["GET"])
# return dictionary with "goal" as key and the value is a nested dictionary

def get_task_by_id(goal_id):
goal = validate_goal(goal_id)

if goal == None:
return []
response_body = { "goal":
{
"id": goal.goal_id,
"title": goal.title,
}
}

return response_body

# GET ALL ROUTE
@goals_bp.route("", methods=["GET"])
def get_all_goals():

goals = Goal.query.all()

if goals == None:
return []
else:
response_body = []
for goal in goals:
response_body.append({
"id": goal.goal_id,
"title": goal.title,
})

return jsonify(response_body)

# # Update ONE Goal
@goals_bp.route("/<goal_id>", methods=["PUT"])

def update_task_by_id(goal_id):

goal = validate_goal(goal_id)
request_body = request.get_json()

goal.title = request_body["title"]


response_body = { "goal":
{
"id": goal.goal_id,
"title": goal.title,
}
}

db.session.commit()

return response_body


@goals_bp.route("/<goal_id>", methods=["DELETE"])

def delete_goal_by_id(goal_id):
goal = validate_goal(goal_id)

db.session.delete(goal)
db.session.commit()

response_body = {
"details":
f"Goal {goal.goal_id} \ {goal.title} \" successfully deleted"
}

return response_body


# NESTED ROUTE CREATE BY GOAL AND TASK
# CREATE A GOAL THATS LINKED TO A TASK
# USE THE GOALS bp

@goals_bp.route("/<goal_id>/tasks", methods=["POST"])

def post_list_of_ids(goal_id):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this function name more specific. Something like post_tasks_for_goal

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completed

goal = validate_goal(goal_id)
request_body = request.get_json()

for task_id in request_body["task_ids"]:
linked_task = Task.query.get(task_id)
linked_task.goal_id = goal_id

db.session.commit()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be moved to line 149

print(goal.tasks)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove print statements unless its beneficial for the user


linked_task_ids = []
for task in goal.tasks:
linked_task_ids.append(task.task_id)

return {"id":goal.goal_id, "task_ids":linked_task_ids}, 200


@goals_bp.route("/<goal_id>/tasks", methods=["GET"])
def get_tasks_one_goal(goal_id):

goal = validate_goal(goal_id)

tasks_response = []
for task in goal.tasks:
tasks_response.append({
"id": goal.goal_id,
"title": goal.title,
"tasks": [
{
"id": task.task_id,
"goal_id": goal.goal_id,
"title": task.title,
"description": task.description,
"is_complete": True if task.completed_at else False
}
]
})
return jsonify(tasks_response)
6 changes: 5 additions & 1 deletion app/models/goal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@


class Goal(db.Model):
goal_id = db.Column(db.Integer, primary_key=True)
goal_id = db.Column(db.Integer, primary_key=True, autoincrement=True)

title = db.Column(db.Text)

tasks = db.relationship("Task", back_populates ="goal", lazy=True)
8 changes: 7 additions & 1 deletion app/models/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@


class Task(db.Model):
task_id = db.Column(db.Integer, primary_key=True)
task_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String)
title = db.Column(db.Text)
description = db.Column(db.Text)
completed_at = db.Column(db.DateTime, nullable= True)
goal_id = db.Column(db.Integer, db.ForeignKey('goal.goal_id'))
goal = db.relationship("Goal", back_populates = "tasks")
Loading