-
Notifications
You must be signed in to change notification settings - Fork 720
Crow_lexy Le task_list_api #89
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
base: main
Are you sure you want to change the base?
Conversation
|
|
||
|
|
||
| The result show as below | ||
|  |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for including the image ^_^
app/__init__.py
Outdated
| from dotenv import load_dotenv | ||
| load_dotenv() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were you running into an issue that required calling load_dotenv() from here?
We need to call load_dotenv() in conftest.py to load up variables for the testing flow, but that shouldn't be necessary in production mode if we've configured things the same as we did for the hello-books and solar-system APIs.
If this code is not necessary, then we should remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I have duplicated , the one in init removed in my update commit, thanks
app/models/goal.py
Outdated
| @@ -1,5 +1,25 @@ | |||
| from sqlalchemy.orm import Mapped, mapped_column | |||
| from sqlalchemy.orm import Mapped, mapped_column,relationship | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small spacing issue:
| from sqlalchemy.orm import Mapped, mapped_column,relationship | |
| from sqlalchemy.orm import Mapped, mapped_column, relationship |
The same issue for the same import shows up in the Task model file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated.thanks
app/models/goal.py
Outdated
| from sqlalchemy.orm import Mapped, mapped_column,relationship | ||
| from ..db import db | ||
| from sqlalchemy import String | ||
| #from sqlalchemy import Date |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If an import was not required, the line should be removed completely before merging code from our branch into the main repo.
app/models/task.py
Outdated
|
|
||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small spacing issue, PEP8 best practices are to use a single line to separate methods within a class to visually show that these are closely related.
app/routes/task_routes.py
Outdated
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Best practices are that we should only have a single blank line at most separating lines inside of a function. More lines makes the reader think the function has ended and can be very confusing when trying to quickly read through code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the headsup
app/routes/task_routes.py
Outdated
| if not current_app.config.get("TESTING"): | ||
| response = requests.post( | ||
| "https://slack.com/api/chat.postMessage", | ||
| headers={"Authorization": f"Bearer {slack_token}"}, | ||
|
|
||
| json={"channel": slack_channel, "text": message} | ||
| ) | ||
| if current_app.config.get("TESTING"): | ||
| return Response(status=204, mimetype="application/json") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could make this a little more concise and unindent the main flow of the application by first checking if we are in testing mode:
if current_app.config.get("TESTING"):
return Response(status=204, mimetype="application/json")
response = requests.post(
"https://slack.com/api/chat.postMessage",
headers={"Authorization": f"Bearer {slack_token}"},
json={"channel": slack_channel, "text": message}
) If we handle the edge case return first, then if we move past that without returning we must be on the production path and do not need to indent it with an if-statement to check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if not current_app.config.get("TESTING"):
response = requests.post(
"https://slack.com/api/chat.postMessage",
headers={"Authorization": f"Bearer {slack_token}"},
json={"channel": slack_channel, "text": message}
)
return Response(status=204, mimetype="application/json") , not sure how to avoid using if ..
app/routes/task_routes.py
Outdated
| return Response(status=204, mimetype="application/json") | ||
|
|
||
|
|
||
| return jsonify({"task": task.to_dict()}), 200 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is not meeting the specification in the project READMEs. The function returns a different result in production vs when in testing. This would not be acceptable in a development team since the tests are not actually testing what the end user would see.
This function needs to be revisited to return the same response no matter what mode we are in. What would need to change to gracefully handle ignoring the slack message if the token isn't set or we are in testing mode?
| def create_model(cls, model_data): | ||
| try: | ||
| new_model = cls.from_dict(model_data) | ||
| except KeyError as e: | ||
| #response = {"message": f"Invalid request: missing {e.args[0]}"} | ||
| #abort(make_response(response, 400)) | ||
| abort(make_response({"details": "Invalid data"}, 400)) | ||
|
|
||
| db.session.add(new_model) | ||
| db.session.commit() | ||
|
|
||
| return new_model.to_dict(), 201 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this both creates a model and creates an http response, I'd consider renaming this to create_model_and_response. Or to better follow single responsibility principles, we could split this into 2 functions:
- one function that only manages creating and returns the new model
- one function that uses the function above to get the model, then creates and returns the response based on that model.
app/routes/route_utilities.py
Outdated
| #response = {"message": f"Invalid request: missing {e.args[0]}"} | ||
| #abort(make_response(response, 400)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove commented code before opening PRs.
…per function and remove all jsonify
app/routes/task_routes.py
Outdated
|
|
||
| db.session.commit() | ||
|
|
||
| return Response(status = 204,mimetype ="application/json") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small spacing issues.
We don't include spaces around the = when we are filling out a keyword argument in a function invocation.
- This differs from when it is used for variable assignment or as part of a comparison operator where we always surround
=in spaces.
| return Response(status = 204,mimetype ="application/json") | |
| return Response(status=204, mimetype="application/json") |
| if current_app.config.get("TESTING"): | ||
| return Response(status=204, mimetype="application/json") | ||
| #if current_app.config.get("TESTING"): | ||
| return Response(status=204, mimetype="application/json") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice restructuring so the message is only sent in production mode, but we always return the same response.
|
|
||
| return jsonify(new_goal.to_dict()), 201 | ||
| #return jsonify(new_goal.to_dict()), 201 | ||
| return create_model(Goal,request_body) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice update to use create_model for the Goal class! Is there a reason we cannot use it for Tasks as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just updated
app/routes/goal_routes.py
Outdated
| # try: | ||
| # new_goal = Goal.from_dict(request_body) | ||
| # except KeyError: | ||
| # return jsonify({"details": "Invalid data"}), 400 | ||
|
|
||
| db.session.add(new_goal) | ||
| db.session.commit() | ||
| # db.session.add(new_goal) | ||
| # db.session.commit() | ||
|
|
||
| return jsonify(new_goal.to_dict()), 201 | ||
| #return jsonify(new_goal.to_dict()), 201 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As part of these updates, please follow best practices to remove the old code once the refactor is working as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure!
bc464ac to
6e7836f
Compare
app/models/task.py
Outdated
| id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) | ||
| title: Mapped[str] = mapped_column(String(100), nullable=False) | ||
| description: Mapped[str] = mapped_column(String(255)) | ||
| completed_at:Mapped[datetime.date] = mapped_column(Date, nullable=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is referencing two different data types datetime.date and sqlalchemy.Date:
completed_at:Mapped[datetime.date] = mapped_column(Date, nullable=True)It seems like some kind of type coercion might be happening under the hood such that we are not running into errors, but this can lead to bugs or unexpected behavior if changes to either data type in the future means that the type coercion fails.
Depending on the requirements of a project we might choose one type or the other, but as with many programming best practices, it's most important to choose a single type and be consistent across the project with what you use. For this project either datetime.date or sqlalchemy.Date works here, but we should choose only one of them.
all tests passed with the picture of wave4