Skip to content

Accelerate -Cadence #1

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

Open
wants to merge 8 commits into
base: master
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
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()'
6 changes: 4 additions & 2 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ def create_app(test_config=None):
# Import models here for Alembic setup
from app.models.task import Task
from app.models.goal import Goal

from .routes import tasks_bp
from .routes import goals_bp
db.init_app(app)
migrate.init_app(app, db)

# Register Blueprints here

app.register_blueprint(tasks_bp)
app.register_blueprint(goals_bp)
return app
2 changes: 2 additions & 0 deletions app/models/goal.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@

class Goal(db.Model):
goal_id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.Text)
task_id = db.relationship("Task", backref='goal', lazy=True)
7 changes: 7 additions & 0 deletions app/models/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,10 @@

class Task(db.Model):
task_id = db.Column(db.Integer, primary_key=True)
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'))



253 changes: 252 additions & 1 deletion app/routes.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,253 @@
from flask import Blueprint

from app import db
from app.models.task import Task
from app.models.goal import Goal
from flask import request, Blueprint, make_response, jsonify
from sqlalchemy import asc, desc
from datetime import datetime
import os
import requests

tasks_bp = Blueprint("tasks", __name__, url_prefix="/tasks")
goals_bp = Blueprint('goals', __name__, url_prefix='/goals')

def is_complete(completed_at):

if completed_at is None:
return False
else:
return True
Comment on lines +14 to +19
Copy link

Choose a reason for hiding this comment

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

great use of helper functions

token=os.environ.get('SLACK_TOKEN')

@tasks_bp.route("", methods=["GET", "POST"])
def handle_tasks():

if request.method == "GET":
tasks = Task.query.all()
title_query = request.args.get("sort")
if title_query == "asc":
tasks = Task.query.order_by(asc(Task.title))
elif title_query == "desc":
tasks = Task.query.order_by(desc(Task.title))

tasks_response = []

for task in tasks:
if task.completed_at is None :
tasks_response.append({
"id": task.task_id,
"title": task.title,
"description": task.description,
"is_complete" : False
})
else:
tasks_response.append({
"id": task.task_id,
"title": task.title,
"description": task.description,
"completed_at": task.completed_at,
"is_complete" : False
})
return jsonify(tasks_response), 200

if request.method == "POST":
request_body = request.get_json()
if "title" not in request_body or "description" not in request_body or "completed_at" not in request_body:
return make_response({
"details": "Invalid data"
}, 400)
else:
new_task = Task(title=request_body["title"], description=request_body["description"], completed_at=request_body["completed_at"])
db.session.add(new_task)
db.session.commit()
return make_response(
{ "task": {
"id": new_task.task_id,
"title": new_task.title,
"description": new_task.description,
"is_complete": is_complete(new_task.completed_at)
}}, 201)
Comment on lines +53 to +69
Copy link

Choose a reason for hiding this comment

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

💃🏽


@tasks_bp.route("/<task_id>", methods=["GET","PUT", "DELETE"])
def handle_tasks_id(task_id):
task = Task.query.get(task_id)
if task is None:
return make_response("", 404)

if request.method == "GET":
if task is not None:
return {"task":{
"id": task.task_id,
"title": task.title,
"description": task.description,
"is_complete": False
}}


elif request.method == "PUT":
data = request.get_json()

task.title = data["title"]
task.description = data["description"]
task.completed_at = data["completed_at"]

db.session.commit()

data_response= {
"task": {
"id": task.task_id,
"title": task.title,
"description": task.description,
"is_complete": is_complete(task.completed_at)
}
}
return make_response(jsonify(data_response),200)


elif request.method == "DELETE":
db.session.delete(task)
db.session.commit()

delete_id_response= f'Task {task.task_id} "{task.title}" successfully deleted'

return make_response(jsonify({"details":delete_id_response}))


@tasks_bp.route("/<task_id>/mark_complete", methods = ["PATCH"])
def handle_complete(task_id):
task = Task.query.get(task_id)

if task is None :
return make_response("", 404)

task.completed_at = datetime.now()

db.session.commit()

slack_url='https://slack.com/api/chat.postMessage'
token= os.environ.get("SLACK_TOKEN")
params = {
'channel': 'task-notifications',
'text': f'Someone just completed the task {task.title}'
}
headers={
'Content-type': 'application/json',
'Authorization': f"Bearer {token}"
}

requests.post(slack_url,json=params,headers=headers)
data_response = {
"task": {
"id": task.task_id,
"title": task.title,
"description": task.description,
"is_complete": True
}
}
Comment on lines +139 to +146
Copy link

Choose a reason for hiding this comment

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

💃🏽



return make_response(jsonify(data_response),200)



@tasks_bp.route("/<task_id>/mark_incomplete", methods = ["PATCH"])
def handle_incomplete(task_id):
task = Task.query.get(task_id)

if task is None:
return make_response("",404)

data_response = {
"task": {
"id": task.task_id,
"title": task.title,
"description": task.description,
"is_complete": False
}
}
db.session.commit()
if task.completed_at is None :
return make_response(jsonify(data_response),200)
Comment on lines +169 to +170
Copy link

Choose a reason for hiding this comment

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

you do not need this check here


task.completed_at = None
Copy link

Choose a reason for hiding this comment

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

I would move this to line 156

return make_response(jsonify(data_response),200)




# Routes for Goal

@goals_bp.route("", methods=["GET","POST"])
def handle_goals():
goal_reponse=[]
goals = Goal.query.all()
Comment on lines +182 to +183
Copy link

@tgoslee tgoslee Jun 19, 2021

Choose a reason for hiding this comment

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

move these after if request.method == 'GET':


if request.method == "GET":

for goal in goals:

Copy link

Choose a reason for hiding this comment

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

Suggested change

goal_reponse.append({
"id": goal.goal_id,
"title":goal.title,
})
return make_response(jsonify(goal_reponse),200)

else:
Copy link

@tgoslee tgoslee Jun 19, 2021

Choose a reason for hiding this comment

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

want to make sure request.mthod == 'POST here

Suggested change
else:
elif request.method == 'POST':

request_body = request.get_json()
if "title" not in request_body:
return make_response({"details": "Invalid data"}, 400)
new_goal = Goal(title = request_body["title"])
db.session.add(new_goal)
db.session.commit()
response_data = {
"goal": {
'id': new_goal.goal_id,
"title":new_goal.title

}

}

return make_response(response_data,201)





@goals_bp.route("/<goal_id>", methods= ["GET","PUT","DELETE"])
def handle_goal_id(goal_id):
goal = Goal.query.get(goal_id)
if goal is None:
return make_response("",404)
if request.method == "GET":
if goal is not None:
Copy link

@tgoslee tgoslee Jun 19, 2021

Choose a reason for hiding this comment

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

you don't need this line again because you already did the check

Suggested change
if goal is not None:

return {
"goal":{
"id" : goal.goal_id,
"title": goal.title
}
}

elif request.method == "PUT":
data = request.get_json()
goal.title= data["title"]
db.session.commit()

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

return make_response(data_response)

elif request.method == "DELETE":
db.session.delete(goal)
db.session.commit()
delete_id_response= f'Goal {goal_id} "{goal.title}" successfully deleted'
return make_response(jsonify({"details":delete_id_response}))

# @goals_bp.route('<goal_id>/tasks', methods=["GET", "POST"])
Copy link

Choose a reason for hiding this comment

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

To get tests passing for Wave 6 go ahead and implement what you started. Go back and look at the video if you need help with the implementation https://adaacademy.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=0e99645b-d46b-4e64-b5fe-ad48012e1e3e



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