Skip to content

Pine - Mac P. #71

Open
mac6551 wants to merge 10 commits intoAda-C16:masterfrom
mac6551:master
Open

Pine - Mac P. #71
mac6551 wants to merge 10 commits intoAda-C16:masterfrom
mac6551:master

Conversation

@mac6551
Copy link

@mac6551 mac6551 commented Nov 5, 2021

Would love tips with refactoring and adding code to check for errors/invalid data.

Copy link

@alope107 alope107 left a comment

Choose a reason for hiding this comment

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

Awesome job Mac! This is a huge project and it looks to all be working! You've got some really excellent docstrings and well-organized code. There's some more detailed feedback and suggestions for next time in the line-byline comments, but this project is definitely green! 🎉

Comment on lines +11 to +19
def valid_id(model, id):
"""If ID is an int, returns the model object with that ID.
If ID is not an int, returns 400.
If model object with that ID doesn't exist, returns 404."""
try:
id = int(id)
except:
abort(400, {"error": "invalid id"})
return model.query.get_or_404(id)
Copy link

Choose a reason for hiding this comment

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

Very cool method with great docstring! However, it's duplicated across both of your routes files. Consider adding an additional file, perhaps named validation.py where this function can live. Then each of your routes files can do from validation import valid_id.

from app.models.task import Task
from dotenv import load_dotenv

load_dotenv()
Copy link

Choose a reason for hiding this comment

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

We don't get the value of any environment variables in this file, so we don't need this line.


@goals_bp.route("", methods=["POST", "GET"])
def handle_goals():
"""Handles post and get requests for /goals"""
Copy link

Choose a reason for hiding this comment

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

Nice docstring here and throughout all your code


if request.method == "GET":
goals = Goal.query.all()
goals_response = [goal.to_dict() 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.

Nice list comprehension!

"""Handles get, put, and delete requests for one goal \
with a given id at goals/<goal_id>"""
goal_dict = {}
goal = valid_id(Goal, goal_id)
Copy link

Choose a reason for hiding this comment

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

Good use of your validator

Comment on lines +52 to +53
for task in tasks:
tasks_response.append(task.to_dict())
Copy link

Choose a reason for hiding this comment

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

This definitely works well! Can you think of what this would look like as a list comprehension instead. Either is good, it's just a matter of personal preference~

Comment on lines +40 to +41
tasks_dict = {}
tasks_dict["task"] = new_task.to_dict()
Copy link

Choose a reason for hiding this comment

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

You could consider combining these two lines into one:

tasks_dict = {
    "task": new_task.to_dict()
}

Comment on lines +86 to +87
SLACK_BOT_TOKEN = os.environ.get("SLACK_BOT_TOKEN")
SLACK_CHANNEL = os.environ.get("SLACK_CHANNEL")
Copy link

Choose a reason for hiding this comment

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

Great variable names! And I really like that the channel is configurable via environment variables as well.

You might consider putting the os.environ.gets somewhere else. Right now, your code re-reads the env vars every time a task is completed. It might be better to read these variables just once when the app starts up, similar to what happens for the DB connection string in app/init.py

"Authorization": f"Bearer {SLACK_BOT_TOKEN}"
}
# response variable left for debugging purposes
response = requests.post(url, data=query_params, headers=headers)
Copy link

Choose a reason for hiding this comment

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

Nice post! An extension that we could do if this were a full production application would be to check the response code that we get back. If it's some error code, we could raise some exception for our application to handle.

Comment on lines +81 to +90
assert response.status_code == 200
assert "goal" in response_body
assert response_body == {
"goal": {
"id": 1,
"title": "Updated Goal Title"
}
}
goal = Goal.query.get(1)
assert goal.title == "Updated Goal Title"
Copy link

Choose a reason for hiding this comment

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

Nice job asserting both the values of the response and what's stored in the database.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants