comments.py
This file defines API endpoints for managing user comments on posts, including creation, retrieval, update, and deletion. It ensures proper authentication, authorization, and data validation for all comment operations.
Scope
-
Defines RESTful API endpoints for comment resources.
-
Authenticates and authorizes user requests for comment actions.
-
Validates incoming comment data using Pydantic schemas.
-
Orchestrates comment creation, retrieval, update, and deletion workflows.
-
Handles error conditions and provides appropriate HTTP responses to clients.
Imports
-
APIRouter from fastapiImports
APIRouterto create a new router instance, enabling the definition of API endpoints for comment-related operations. It organizes routes and applies common configurations effectively. -
Depends from fastapiImports
Dependsfor dependency injection, allowing functions likeget_dbandget_tokento provide shared resources or logic to route handlers. This promotes reusability and testability. -
status from fastapiImports
statusto access standard HTTP status codes, ensuring consistent and semantically correct responses for API operations. This improves client understanding of request outcomes. -
HTTPException from fastapiImports
HTTPExceptionto raise standard HTTP errors within route handlers, providing structured error responses to API clients. This ensures consistent error handling across the application. -
Query from fastapiImports
Queryto define and validate query parameters for API endpoints, such as pagination controls likeskipandlimit. This ensures robust and flexible data retrieval. -
Session from sqlalchemy.ormImports
Sessionfrom SQLAlchemy's ORM, representing a database session. This is crucial for interacting with the database, managing transactions, and performing CRUD operations on models. -
get_db from app.core.databaseImports
get_dbas a dependency to provide a database session to route handlers. This ensures proper database connection management and resource cleanup for each request. -
get_token from app.core.securityImports
get_tokenas a dependency to extract and validate authentication tokens from incoming requests. This is fundamental for securing API endpoints and identifying the current user. -
CommentCreate, CommentUpdate, CommentResponse from app.schemas.schemasImports Pydantic schemas (
CommentCreate,CommentUpdate,CommentResponse) for data validation, serialization, and deserialization of comment-related request bodies and response models. This ensures data integrity. -
CommentService, PostService, UserService from app.services.serviceImports various service classes (
CommentService,PostService,UserService) to encapsulate business logic and data access operations for comments, posts, and users. This promotes modularity and separation of concerns. -
logger from app.core.loggingImports the
loggerinstance for structured logging of application events, errors, and debugging information. This is essential for monitoring application health and troubleshooting issues effectively.
Variables
routerThe
APIRouterinstance configured with a base prefix and tags for comment-related endpoints. It aggregates all comment routes, making them discoverable and manageable within the API documentation.
Global Code
Initializes the FastAPI APIRouter for comment-related endpoints, setting a common URL prefix and grouping them under the 'Comments' tag for API documentation. This organizes the API structure.
Routers
router
This `router` manages all API endpoints for user comments, providing a dedicated interface for comment operations. It organizes routes for creating, retrieving, updating, and deleting comments. This module integrates seamlessly, enhancing modularity and maintainability.
/api/v1/comments
Tags
Comments
Functions
get_current_user
public
Retrieves the currently authenticated user based on the provided token payload. This function is crucial for protecting API endpoints, ensuring only valid, authenticated users can access specific resources and perform authorised actions.
def get_current_user(token_payload: dict = Depends(get_token), db: Session = Depends(get_db)):
-
token_payload(dict)Dictionary containing decoded JWT token payload, typically injected by
get_tokendependency. It must contain asubkey representing the user's ID for successful user retrieval and authentication purposes. -
db(Session)Database session dependency, injected by
get_db, providing access to the database. This session is essential for querying theUserServiceto fetch user details based on the extracted user ID.
user(User)The
Userobject corresponding to theuser_idextracted from thetoken_payload. This object represents the authenticated user, allowing subsequent operations to access user-specific data and permissions securely.
HTTPException 404 Not Found[404]Raised when
UserService.get_user_by_idreturnsNone, indicating no user was found for the givenuser_id. This signifies an invalid or non-existent user associated with the provided authentication token.
- Extract the
user_idfrom thetoken_payloaddictionary using thesubkey, converting it to an integer. - Call
UserService.get_user_by_idwith the database sessiondband the extracteduser_idto retrieve the user. - Check if the
userobject returned fromUserServiceisNone:- If
userisNone(user not found):- Raise an
HTTPExceptionwith a404 Not Foundstatus code and detail message 'User not found'.
- Raise an
- If
- If a
userobject is successfully retrieved, return theuserobject.
Usage Tips
-
Always use
get_current_useras aDependsdependency in your FastAPI path operations to automatically handle user authentication. This ensures only authenticated requests proceed, simplifying endpoint security significantly. -
Ensure your
get_tokendependency correctly extracts and validates JWTs, populating thetoken_payloadwith a reliablesub(subject) field. Thissubfield is critical for identifying the user.
Additional Notes
-
This function relies on
UserService.get_user_by_idto fetch user details; ensure this service method is robust and handles database interactions efficiently. Performance here directly impacts authentication latency. -
The
user_idis cast to an integer; ensure that thesubclaim in your JWTtoken_payloadis always an integer or a string representation of an integer to prevent type conversion errors.
Routes
GET /{comment_id}
This route retrieves a specific comment using its unique `comment_id` from the path. It queries the database for the comment. If not found, a `404 Not Found` error is raised. Otherwise, the comment data is returned successfully.
GET /{comment_id}
comment_id(int)The unique integer identifier for the comment to be retrieved. This path parameter is used to query the database for the specific comment record.
db(Session)The database session dependency injected into the route handler. This
Sessionobject provides the necessary connection and methods for interacting with the database to fetch comment data.
comment_id(int)The unique integer identifier for the comment to be retrieved. This
comment_idis extracted directly from the URL path segment and used for database lookup.
CommentResponse(CommentResponse)A
CommentResponseobject representing the retrieved comment data. This object is constructed from the database model and returned upon successful retrieval of the comment.
404 Not Found: This status is returned when no comment matching the providedcomment_idis found in the database. The response includes adetailmessage: 'Comment not found'.
- Receive
GETrequest for/{comment_id}with path parametercomment_id. - Obtain a database session
dbusing dependency injection. - Call
CommentService.get_comment_by_idwithdbandcomment_idto fetch the comment. - Check if the
db_commentobject returned from the service isNone.- If
db_commentisNone: Raise anHTTPExceptionwithstatus_code=404anddetail="Comment not found".
- If
- If
db_commentis notNone: Convertdb_commenttoCommentResponseusingCommentResponse.from_orm(). - Return the
CommentResponseobject.
Usage Tips
-
Always ensure the
comment_idprovided in the URL path is a valid integer. Providing a non-integer or non-existent ID will result in an error response. -
Handle the
404 Not Foundresponse gracefully in your client application. This indicates the requested comment does not exist, requiring appropriate user feedback.
Additional Notes
-
The
CommentResponsemodel ensures consistent data serialization for comments. This abstraction separates the internal database representation from the external API response structure. -
This endpoint relies on
CommentServicefor database interaction, centralizing data access logic. Theget_dbdependency ensures proper database session management for each request.
GET /{comment_id}
This route retrieves a specific comment using its unique `comment_id` from the path. It queries the database for the comment. If not found, a `404 Not Found` error is raised. Otherwise, the comment data is returned successfully.
GET /{comment_id}
comment_id(int)The unique integer identifier for the comment to be retrieved. This path parameter is used to query the database for the specific comment record.
db(Session)The database session dependency injected into the route handler. This
Sessionobject provides the necessary connection and methods for interacting with the database to fetch comment data.
comment_id(int)The unique integer identifier for the comment to be retrieved. This
comment_idis extracted directly from the URL path segment and used for database lookup.
CommentResponse(CommentResponse)A
CommentResponseobject representing the retrieved comment data. This object is constructed from the database model and returned upon successful retrieval of the comment.
404 Not Found: This status is returned when no comment matching the providedcomment_idis found in the database. The response includes adetailmessage: 'Comment not found'.
- Receive
GETrequest for/{comment_id}with path parametercomment_id. - Obtain a database session
dbusing dependency injection. - Call
CommentService.get_comment_by_idwithdbandcomment_idto fetch the comment. - Check if the
db_commentobject returned from the service isNone.- If
db_commentisNone: Raise anHTTPExceptionwithstatus_code=404anddetail="Comment not found".
- If
- If
db_commentis notNone: Convertdb_commenttoCommentResponseusingCommentResponse.from_orm(). - Return the
CommentResponseobject.
Usage Tips
-
Always ensure the
comment_idprovided in the URL path is a valid integer. Providing a non-integer or non-existent ID will result in an error response. -
Handle the
404 Not Foundresponse gracefully in your client application. This indicates the requested comment does not exist, requiring appropriate user feedback.
Additional Notes
-
The
CommentResponsemodel ensures consistent data serialization for comments. This abstraction separates the internal database representation from the external API response structure. -
This endpoint relies on
CommentServicefor database interaction, centralizing data access logic. Theget_dbdependency ensures proper database session management for each request.
GET /{comment_id}
This route retrieves a specific comment using its unique `comment_id` from the path. It queries the database for the comment. If not found, a `404 Not Found` error is raised. Otherwise, the comment data is returned successfully.
GET /{comment_id}
comment_id(int)The unique integer identifier for the comment to be retrieved. This path parameter is used to query the database for the specific comment record.
db(Session)The database session dependency injected into the route handler. This
Sessionobject provides the necessary connection and methods for interacting with the database to fetch comment data.
comment_id(int)The unique integer identifier for the comment to be retrieved. This
comment_idis extracted directly from the URL path segment and used for database lookup.
CommentResponse(CommentResponse)A
CommentResponseobject representing the retrieved comment data. This object is constructed from the database model and returned upon successful retrieval of the comment.
404 Not Found: This status is returned when no comment matching the providedcomment_idis found in the database. The response includes adetailmessage: 'Comment not found'.
- Receive
GETrequest for/{comment_id}with path parametercomment_id. - Obtain a database session
dbusing dependency injection. - Call
CommentService.get_comment_by_idwithdbandcomment_idto fetch the comment. - Check if the
db_commentobject returned from the service isNone.- If
db_commentisNone: Raise anHTTPExceptionwithstatus_code=404anddetail="Comment not found".
- If
- If
db_commentis notNone: Convertdb_commenttoCommentResponseusingCommentResponse.from_orm(). - Return the
CommentResponseobject.
Usage Tips
-
Always ensure the
comment_idprovided in the URL path is a valid integer. Providing a non-integer or non-existent ID will result in an error response. -
Handle the
404 Not Foundresponse gracefully in your client application. This indicates the requested comment does not exist, requiring appropriate user feedback.
Additional Notes
-
The
CommentResponsemodel ensures consistent data serialization for comments. This abstraction separates the internal database representation from the external API response structure. -
This endpoint relies on
CommentServicefor database interaction, centralizing data access logic. Theget_dbdependency ensures proper database session management for each request.
POST /post/{post_id}
This route creates a new comment for a specific post identified by post_id. It requires user authentication, validates post existence, and persists the comment data to the database. A successful creation returns the new comment object.
POST /post/{post_id}
post_id(int)This path parameter identifies the specific post to which the comment will be added. It is crucial for linking the new comment to its parent post.
comment_create(CommentCreate)This Pydantic model represents the request body containing the new comment's data. It ensures structured input for comment content and other relevant fields.
current_user(User)This dependency injects the currently authenticated user object. It provides the
user.idfor associating the new comment with its creator.db(Session)This dependency provides a database session object. It is used for all database operations, including fetching the post and creating the new comment.
post_id(int)The
post_idis extracted from the URL path. It specifies the target post for the new comment, ensuring correct association within the system.comment_create(CommentCreate)The request body, parsed into a
CommentCreatePydantic model, contains the actual comment data. This includes the comment's text and any other required fields.current_user.id(int)The authenticated user's ID, obtained from
current_userdependency, is used to link the newly created comment to its author. This ensures proper ownership.
CommentResponse(CommentResponse)Upon successful comment creation, a
CommentResponseobject is returned. This Pydantic model represents the newly created comment, including its ID and content.
201 Created: This status code indicates that the comment was successfully created and persisted in the database. The response body contains the newly createdCommentResponseobject.404 Not Found: This status code is returned if thepost_idprovided in the path does not correspond to an existing post. The comment cannot be created.500 Internal Server Error: This status code indicates an unexpected server-side error during comment creation. It suggests a problem beyond client control, requiring server investigation.
- Receive
POSTrequest for/post/{post_id}withpost_id,comment_createbody,current_user, anddbsession. - Attempt to execute the following operations:
- Retrieve the post from the database using
PostService.get_post_by_idwithdbandpost_id. - Check if the
postobject was found.- If
postisNone: raiseHTTPExceptionwith404status and "Post not found" detail.
- If
- Create a new comment in the database using
CommentService.create_commentwithdb,comment_createdata,post_id, andcurrent_user.id. - Convert the created database comment
db_commentinto aCommentResponsePydantic model usingCommentResponse.from_orm. - Return the
CommentResponseobject with201 Createdstatus.
- Retrieve the post from the database using
- Handle
HTTPExceptionspecifically:- Re-raise the caught
HTTPExceptiondirectly.
- Re-raise the caught
- Handle any other
Exception:- Log the error using
logger.errorwith a descriptive message including the exception details. - Raise
HTTPExceptionwith500 Internal Server Errorstatus and "Error creating comment" detail.
- Log the error using
Usage Tips
-
Always ensure the
post_idexists before attempting to create a comment. A non-existentpost_idwill result in a404 Not Founderror response. -
Provide a valid
CommentCreateobject in the request body. Missing or malformed data will likely lead to validation errors or unexpected server behavior.
Additional Notes
-
This endpoint relies on
get_current_userfor authentication. Ensure a valid authentication token is provided in the request headers to access this resource. -
The
CommentResponse.from_ormconversion ensures that the database object is correctly serialized into the API's defined response format before being sent.
POST /post/{post_id}
This route creates a new comment for a specific post identified by post_id. It requires user authentication, validates post existence, and persists the comment data to the database. A successful creation returns the new comment object.
POST /post/{post_id}
post_id(int)This path parameter identifies the specific post to which the comment will be added. It is crucial for linking the new comment to its parent post.
comment_create(CommentCreate)This Pydantic model represents the request body containing the new comment's data. It ensures structured input for comment content and other relevant fields.
current_user(User)This dependency injects the currently authenticated user object. It provides the
user.idfor associating the new comment with its creator.db(Session)This dependency provides a database session object. It is used for all database operations, including fetching the post and creating the new comment.
post_id(int)The
post_idis extracted from the URL path. It specifies the target post for the new comment, ensuring correct association within the system.comment_create(CommentCreate)The request body, parsed into a
CommentCreatePydantic model, contains the actual comment data. This includes the comment's text and any other required fields.current_user.id(int)The authenticated user's ID, obtained from
current_userdependency, is used to link the newly created comment to its author. This ensures proper ownership.
CommentResponse(CommentResponse)Upon successful comment creation, a
CommentResponseobject is returned. This Pydantic model represents the newly created comment, including its ID and content.
201 Created: This status code indicates that the comment was successfully created and persisted in the database. The response body contains the newly createdCommentResponseobject.404 Not Found: This status code is returned if thepost_idprovided in the path does not correspond to an existing post. The comment cannot be created.500 Internal Server Error: This status code indicates an unexpected server-side error during comment creation. It suggests a problem beyond client control, requiring server investigation.
- Receive
POSTrequest for/post/{post_id}withpost_id,comment_createbody,current_user, anddbsession. - Attempt to execute the following operations:
- Retrieve the post from the database using
PostService.get_post_by_idwithdbandpost_id. - Check if the
postobject was found.- If
postisNone: raiseHTTPExceptionwith404status and "Post not found" detail.
- If
- Create a new comment in the database using
CommentService.create_commentwithdb,comment_createdata,post_id, andcurrent_user.id. - Convert the created database comment
db_commentinto aCommentResponsePydantic model usingCommentResponse.from_orm. - Return the
CommentResponseobject with201 Createdstatus.
- Retrieve the post from the database using
- Handle
HTTPExceptionspecifically:- Re-raise the caught
HTTPExceptiondirectly.
- Re-raise the caught
- Handle any other
Exception:- Log the error using
logger.errorwith a descriptive message including the exception details. - Raise
HTTPExceptionwith500 Internal Server Errorstatus and "Error creating comment" detail.
- Log the error using
Usage Tips
-
Always ensure the
post_idexists before attempting to create a comment. A non-existentpost_idwill result in a404 Not Founderror response. -
Provide a valid
CommentCreateobject in the request body. Missing or malformed data will likely lead to validation errors or unexpected server behavior.
Additional Notes
-
This endpoint relies on
get_current_userfor authentication. Ensure a valid authentication token is provided in the request headers to access this resource. -
The
CommentResponse.from_ormconversion ensures that the database object is correctly serialized into the API's defined response format before being sent.
FAQs
Why is get_current_user implemented as a dependency?
get_current_useris a FastAPI dependency function, ensuring user authentication and retrieval are consistently applied across multiple routes. This promotes reusability and separation of concerns effectively throughout the API layer.
What is the purpose of CommentResponse.from_orm?
CommentResponse.from_ormconverts SQLAlchemy ORM model instances into Pydantic response models. This ensures data serialization, validation, and proper formatting before sending responses to clients, maintaining API contract consistency and clarity.
Why are CommentService, PostService, and UserService used?
These services encapsulate specific business logic and data access for their respective domains. This promotes separation of concerns, reusability, and maintainability, keeping the API layer focused on request handling and orchestration rather than implementation details.
Insights
| Metric | Score | Level |
|---|---|---|
| Complexity | 0.70 | High Complexity |
| Security | 0.80 | Secure |
| Performance | 0.70 | Acceptable Performance |
Complexity
Medium - Repetitive Error Handling Logic
The error handling for
create_comment,update_comment, anddelete_commentis duplicated. Centralizing this logic into a custom exception handler or decorator would improve maintainability and reduce boilerplate.
Security
High - Missing Rate Limiting on Comment Operations
There is no explicit rate limiting implemented for comment creation, update, or deletion endpoints. This could expose the API to abuse, such as spamming or denial-of-service attacks, by malicious users.
Performance
Medium - Potential N+1 Query Issue in Response Model
The
CommentResponse.from_ormconversion might trigger N+1 queries if theCommentResponsemodel accesses related entities (e.g., author details) that are not eagerly loaded by the service layer. This could impact performance.