Browse Source

Refactor to clarify API does not use marshmallow

* Get SimpleHoursPeriod directly, not via marshmallow schema

  Mentioning marshmallow in imports is misleading here, since we are
  constructing the result dict by hand and not using marshmallow
  to generate the OpenAPI response.

* Rename API serialize methods to mention API

  This differentiates from the Marshmallow Schema dump method
  which is used in the JSON renderer in json.py
merge-requests/170/head
Andrew Shu 2 months ago
parent
commit
36628b31e8
  1. 22
      tildes/tildes/views/api/beta/comment.py
  2. 29
      tildes/tildes/views/api/beta/topic.py
  3. 21
      tildes/tildes/views/api/beta/user.py

22
tildes/tildes/views/api/beta/comment.py

@ -8,8 +8,11 @@ from tildes.models.comment import Comment
from tildes.models.comment.comment_tree import CommentInTree
def comment_to_dict(request: Request, comment: Comment) -> dict:
"""Convert a Comment object to a dictionary for JSON serialization."""
def comment_to_api_dict(request: Request, comment: Comment) -> dict:
"""Convert a Comment object to a dictionary for JSON serialization.
The schema is defined in our OpenAPI YAML file.
"""
# Check permissions for viewing comment details (and set safe defaults)
author = None
@ -66,14 +69,21 @@ def comment_to_dict(request: Request, comment: Comment) -> dict:
}
def comment_subtree_to_dict(request: Request, comments: list[CommentInTree]) -> list:
"""Convert a comment subtree to a list of dictionaries for JSON serialization."""
def comment_subtree_to_api_dict(
request: Request, comments: list[CommentInTree]
) -> list:
"""Convert a comment subtree to a list of dictionaries for JSON serialization.
The schema is defined in our OpenAPI YAML file.
"""
comments_list = []
for comment in comments:
comment_dict = comment_to_dict(request, comment)
comment_dict = comment_to_api_dict(request, comment)
comment_dict["depth"] = comment.depth
comment_dict["children"] = (
comment_subtree_to_dict(request, comment.replies) if comment.replies else []
comment_subtree_to_api_dict(request, comment.replies)
if comment.replies
else []
)
comments_list.append(comment_dict)
return comments_list

29
tildes/tildes/views/api/beta/topic.py

@ -3,24 +3,26 @@
"""JSON API endpoints related to topics."""
from marshmallow.exceptions import ValidationError
from pyramid.request import Request
from pyramid.view import view_config
from tildes.enums import CommentTreeSortOption, TopicSortOption
from tildes.models.comment import CommentTree, Comment
from tildes.models.topic import Topic
from tildes.schemas.fields import ShortTimePeriod
from tildes.lib.datetime import SimpleHoursPeriod
from tildes.lib.id import id36_to_id
from tildes.views.api.beta.api_utils import (
build_error_response,
get_next_and_prev_link,
query_apply_pagination,
)
from tildes.views.api.beta.comment import comment_subtree_to_dict
from tildes.views.api.beta.comment import comment_subtree_to_api_dict
def topic_to_dict(topic: Topic) -> dict:
"""Convert a Topic object to a dictionary for JSON serialization."""
def topic_to_api_dict(topic: Topic) -> dict:
"""Convert a Topic object to a dictionary for JSON serialization.
The schema is defined in our OpenAPI YAML file.
"""
return {
"id": topic.topic_id36,
"title": topic.title,
@ -59,10 +61,13 @@ def get_topics(request: Request) -> dict: # noqa
after = request.openapi_validated.parameters.query.get("after", None)
# Parse parameters where necessary
try:
period = ShortTimePeriod(allow_none=True).deserialize(period_raw)
except ValidationError as exc:
return build_error_response(str(exc), field="period")
if not period_raw or period_raw == "all":
period = None
else:
try:
period = SimpleHoursPeriod.from_short_form(period_raw)
except ValueError as exc:
return build_error_response(str(exc), field="period")
try:
if order_raw:
@ -94,7 +99,7 @@ def get_topics(request: Request) -> dict: # noqa
# Build the JSON topic data
for topic in topics:
processed_topic = topic_to_dict(topic)
processed_topic = topic_to_api_dict(topic)
processed_topics.append(processed_topic)
# Construct the paging next and previous link if there are more topics
@ -161,11 +166,11 @@ def get_topic(request: Request) -> dict:
tree.uncollapse_new_comments(topic.last_visit_time)
tree.finalize_collapsing_maximized()
commentsjson = comment_subtree_to_dict(request, tree.tree)
commentsjson = comment_subtree_to_api_dict(request, tree.tree)
# Construct the final response JSON object
response = {
"topic": topic_to_dict(topic),
"topic": topic_to_api_dict(topic),
"comments": commentsjson,
}
return response

21
tildes/tildes/views/api/beta/user.py

@ -15,12 +15,15 @@ from tildes.views.api.beta.api_utils import (
get_next_and_prev_link,
query_apply_pagination,
)
from tildes.views.api.beta.comment import comment_to_dict
from tildes.views.api.beta.topic import topic_to_dict
from tildes.views.api.beta.comment import comment_to_api_dict
from tildes.views.api.beta.topic import topic_to_api_dict
def _user_to_dict(user: User) -> dict:
"""Convert a User object to a dictionary for JSON serialization."""
def _user_to_api_dict(user: User) -> dict:
"""Convert a User object to a dictionary for JSON serialization.
The schema is defined in our OpenAPI YAML file.
"""
return {
"username": user.username,
"joined_at": user.created_time.isoformat(),
@ -85,16 +88,16 @@ def get_user(request: Request) -> dict: # noqa
processed_results = []
for item in combined_results.results:
if isinstance(item, Topic):
processed_results.append(topic_to_dict(item))
processed_results.append(topic_to_api_dict(item))
elif isinstance(item, Comment):
processed_results.append(comment_to_dict(request, item))
processed_results.append(comment_to_api_dict(request, item))
# Construct the paging next and previous link if there are more topics
(next_link, prev_link) = get_next_and_prev_link(request, combined_results)
# Construct the final response JSON object
response = {
"user": _user_to_dict(user),
"user": _user_to_api_dict(user),
"history": processed_results,
"pagination": {
"num_items": len(processed_results),
@ -144,7 +147,7 @@ def get_user_comments(request: Request) -> dict:
# Build the JSON history data
processed_comments = []
for comment in query_result.results:
processed_comments.append(comment_to_dict(request, comment))
processed_comments.append(comment_to_api_dict(request, comment))
# Construct the paging next and previous link if there are more comments
(next_link, prev_link) = get_next_and_prev_link(request, query_result)
@ -200,7 +203,7 @@ def get_user_topics(request: Request) -> dict:
# Build the JSON history data
processed_topics = []
for topic in query_result.results:
processed_topics.append(topic_to_dict(topic))
processed_topics.append(topic_to_api_dict(topic))
# Construct the paging next and previous link if there are more topics
(next_link, prev_link) = get_next_and_prev_link(request, query_result)

Loading…
Cancel
Save