Skip to content

Possum - Amanda Thompson#30

Open
tthoaman wants to merge 2 commits intoAda-C24:mainfrom
tthoaman:main
Open

Possum - Amanda Thompson#30
tthoaman wants to merge 2 commits intoAda-C24:mainfrom
tthoaman:main

Conversation

@tthoaman
Copy link
Copy Markdown

@tthoaman tthoaman commented Nov 7, 2025

No description provided.

Comment thread app/__init__.py
Comment on lines +4 to +5
from .routes.task_routes import tasks_bp
from .routes.goal_routes import goals_bp
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

To be more consistent with Flask and API patterns, we should name our blueprints bp, and in other files like __init__.py here we should import them with more specific names if necessary.

Comment thread app/models/goal.py

class Goal(db.Model):
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
title: Mapped[str] = mapped_column(nullable=False)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nullable=False is the default value for an attribute in SQLAlchemy. It is more common to leave off the mapped_column content unless we are changing a setting to something other than the default value.

class Goal(db.Model):
    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    title: Mapped[str]
    tasks: Mapped[list["Task"]] = relationship(back_populates="goal")

Comment thread app/models/task.py
description: Mapped[str] = mapped_column(nullable=False)
completed_at: Mapped[Optional[datetime]] = mapped_column(nullable=True)
goal_id: Mapped[Optional[int]] = mapped_column(ForeignKey("goal.id"))
goal: Mapped[Optional["Goal"]] = db.relationship("Goal", back_populates="tasks")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We should be consistent with the syntax we use across a project to avoid confusion.

Since in Goal.py we use the shorthand relationship() function to create the convenience attribute tasks, it would make our code more concise and consistent to use the same syntax for the goal relationship here in Task.py.

What would the updated attribute look like with that change?

Comment thread app/models/task.py
description = task_data["description"]
completed_at = task_data.get("completed_at", None)
goal_id = task_data.get("goal_id", None)
return cls(title=title, description=description, completed_at=completed_at, goal_id=goal_id)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

How can we break up this line to keep within PEP8 best practices of 79 characters or less?

Comment thread app/models/task.py
Comment on lines 8 to +11
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
title: Mapped[str] = mapped_column(nullable=False)
description: Mapped[str] = mapped_column(nullable=False)
completed_at: Mapped[Optional[datetime]] = mapped_column(nullable=True)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Take a look at the the feedback around nullable for attributes on the Goal class.

  • What attributes here on the Task class does this feedback also apply to?
  • What would it look like to update those attributes?

Comment thread app/models/task.py
Comment on lines +31 to +32
completed_at = task_data.get("completed_at", None)
goal_id = task_data.get("goal_id", None)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Great use of get for the optional values.

Comment thread app/routes/goal_routes.py
Comment on lines +56 to +60
goal.tasks = []

for id in request_body["task_ids"]:
task = validate_model(Task, id)
task.goal_id = goal.id
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This works, but we can also associate the tasks with a goal by assigning them to the goal.tasks list. A slightly more pythonic way we could do this is by using a list comprehension to gather the new tasks then overwriting goal.tasks:

task_ids = request_body["task_ids"]
new_tasks = [validate_model(Task, id) for id in task_ids]
goal.tasks = new_tasks

@@ -0,0 +1,32 @@
"""empty message
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I am seeing a lot of empty messages in the migration files. Just like with our git commits we should be leaving a descriptive message of changes every time we migrate to help other developers easily be able to track the changes to the database structure over time.

Comment on lines +23 to +34
def create_model(cls, model_data):
try:
new_model = cls.from_dict(model_data)

except KeyError:
response = {'details': f'Invalid data'}
abort(make_response(response, 400))

db.session.add(new_model)
db.session.commit()

return new_model.to_dict(), 201
Copy link
Copy Markdown

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.

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