Skip to content

posts.py

This file defines the API routes for managing blog posts, enabling creation, retrieval, search, update, and deletion. It handles user authentication, authorization, data validation, and delegates core business logic to dedicated service layers, ensuring robust post lifecycle.

Scope

  • Defines RESTful API endpoints for managing blog posts.

  • Authenticates incoming requests and authorizes user actions on posts.

  • Validates request data using Pydantic schemas and query parameters.

  • Orchestrates calls to PostService and UserService for business logic.

  • Handles exceptions and returns appropriate HTTP error responses.

File diagram - "posts.py" /app/routes/posts.pyFile diagram - "posts.py"  GlobalImportsAPIRouterDependsstatusHTTPExceptionQuerySessionget_dbget_tokenPostCreatePostUpdatePostResponsePaginationParamsPostServiceUserServiceSuccessResponselogger/app/routes/posts.pyrouterget_current_user()create_post()list_posts()APIRouter()router.post()router.get()router.put()router.delete()get_current_useruser_iduserDepends()int()token_payload.get()UserService.get_user_by_id()HTTPException()create_postdb_postDepends()PostService.create_post()PostResponse.from_orm()logger.error()str()HTTPException()list_postspostsQuery()Depends()PostService.get_all_posts()PostResponse.from_orm()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
File diagram - "posts.py" /app/routes/posts.pyFile diagram - "posts.py"  GlobalImportsAPIRouterDependsstatusHTTPExceptionQuerySessionget_dbget_tokenPostCreatePostUpdatePostResponsePaginationParamsPostServiceUserServiceSuccessResponselogger/app/routes/posts.pyrouterget_current_user()create_post()list_posts()APIRouter()router.post()router.get()router.put()router.delete()get_current_useruser_iduserDepends()int()token_payload.get()UserService.get_user_by_id()HTTPException()create_postdb_postDepends()PostService.create_post()PostResponse.from_orm()logger.error()str()HTTPException()list_postspostsQuery()Depends()PostService.get_all_posts()PostResponse.from_orm()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Imports

  • APIRouter from fastapi

    This import provides the core functionality for defining API routes and structuring the application's endpoint handlers. It enables modular route definitions for the post management domain.

  • Depends from fastapi

    This import facilitates dependency injection, allowing functions to declare dependencies like database sessions or authenticated users, which FastAPI resolves automatically, promoting modularity.

  • status from fastapi

    This import provides convenient access to standard HTTP status codes, ensuring consistent and semantically correct responses for various API operations, enhancing client understanding.

  • HTTPException from fastapi

    This import is used for raising HTTP-specific exceptions, allowing the API to return structured error responses with appropriate status codes and details, improving error communication.

  • Query from fastapi

    This import enables defining and validating query parameters for API endpoints, ensuring that incoming request parameters adhere to specified types and constraints, enhancing data integrity.

  • Session from sqlalchemy.orm

    This import represents a database session, providing the interface for interacting with the database, performing queries, and managing transactions within the application's data layer.

  • get_db from app.core.database

    This internal dependency provides a function to obtain a database session, ensuring proper connection management and resource handling for all database operations within the application.

  • get_token from app.core.security

    This internal dependency provides a function to extract and validate authentication tokens from incoming requests, securing API endpoints by verifying user identity and access permissions.

  • PostCreate, PostUpdate, PostResponse, PaginationParams from app.schemas.schemas

    These Pydantic schemas define the data structures for creating, updating, and responding with posts, along with pagination parameters, ensuring consistent data validation and serialization.

  • PostService, UserService from app.services.service

    These internal dependencies provide access to the core business logic for managing posts and users, abstracting database interactions and complex operations from the API layer effectively.

  • logger from app.core.logging

    This internal dependency provides a logging utility, enabling the recording of important events, errors, and debugging information for monitoring and troubleshooting the application's runtime behavior.

Variables

  • router

    This APIRouter instance defines the base path and tags for all post-related API endpoints, organizing them logically and enabling modular route registration within the FastAPI application effectively.

Global Code

This line initializes the FastAPI router for post-related API endpoints, setting a common URL prefix and grouping them under the 'Posts' tag for documentation purposes effectively.

Routers

router

This `router` manages all API endpoints for `Post` resources. It organizes routes for creating, retrieving, updating, and deleting posts. This modular structure integrates into the main application, facilitating clear separation.

Prefix

/api/v1/posts

Configuration Details

Tags

  • Posts

Functions

get_current_user

public

This function retrieves the currently authenticated user's details from the database using a provided token payload. It ensures the user exists, providing essential context for subsequent authorized operations and protecting sensitive endpoints requiring user identity.
=== " "

Activity Diagram - "get_current_user" /app/routes/posts.pyActivity Diagram - "get_current_user"  Inputs: token_payload, dbExtract user ID from token payloadRetrieve user from database by IDuser not found?yesnoRaise HTTP 404 exception (User not found)return User object   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_current_user" /app/routes/posts.pyActivity Diagram - "get_current_user"  Inputs: token_payload, dbExtract user ID from token payloadRetrieve user from database by IDuser not found?yesnoRaise HTTP 404 exception (User not found)return User object   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_current_user" /app/routes/posts.pyMethod diagram - "get_current_user"  get_current_useruser_iduserDepends()int()token_payload.get()UserService.get_user_by_id()HTTPException()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_current_user" /app/routes/posts.pyMethod diagram - "get_current_user"  get_current_useruser_iduserDepends()int()token_payload.get()UserService.get_user_by_id()HTTPException()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_current_user" Sequence Diagram - "get_current_user"  get_current_userget_tokenget_dbUserServiceCallerget_current_userget_tokenget_dbUserServiceHTTPExceptionCallerCallerget_current_userget_current_userget_tokenget_tokenget_dbget_dbUserServiceUserServiceHTTPExceptionHTTPExceptionget_current_userget_tokenget_dbUserServiceFunction Entryget_current_user(token_payload, db)Retrieve Token Payloadget_token()token_payloadRetrieve Database Sessionget_db()db_sessionExtract User IDExtract user_id from token_payloaduser_id = int(token_payload.get("sub"))Fetch User from Databaseget_user_by_id(db_session, user_id)user_objectHandle User Not Found or Return Useralt[user_object is None]HTTPException(status_code=404, detail="User not found")Function terminates by raising exceptionraise HTTPException[user_object is not None]user_object/app/routes/posts.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_current_user" Sequence Diagram - "get_current_user"  get_current_userget_tokenget_dbUserServiceCallerget_current_userget_tokenget_dbUserServiceHTTPExceptionCallerCallerget_current_userget_current_userget_tokenget_tokenget_dbget_dbUserServiceUserServiceHTTPExceptionHTTPExceptionget_current_userget_tokenget_dbUserServiceFunction Entryget_current_user(token_payload, db)Retrieve Token Payloadget_token()token_payloadRetrieve Database Sessionget_db()db_sessionExtract User IDExtract user_id from token_payloaduser_id = int(token_payload.get("sub"))Fetch User from Databaseget_user_by_id(db_session, user_id)user_objectHandle User Not Found or Return Useralt[user_object is None]HTTPException(status_code=404, detail="User not found")Function terminates by raising exceptionraise HTTPException[user_object is not None]user_object/app/routes/posts.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_current_user(token_payload: dict = Depends(get_token), db: Session = Depends(get_db)):

Input Parameters

  • token_payload (dict)

    A dictionary containing decoded token information, typically including the user's subject identifier (sub). This payload is crucial for identifying the authenticated user and is injected via get_token dependency.

  • db (Session)

    The SQLAlchemy database session instance, provided by the get_db dependency. This session is essential for interacting with the database to fetch user details and perform necessary data operations.

Output / Return Values

  • user (User)

    The User object retrieved from the database, representing the authenticated user. This object contains all user-specific data required for further processing or to be returned as part of an API response.

Exceptions

  • HTTPException 404 Not Found [404]

    Raised when no user is found in the database corresponding to the user_id extracted from the token payload. This indicates an invalid or revoked token, or a deleted user account.

Logic / Execution Flow

  • Extract the user_id from the token_payload dictionary, converting its value associated with the sub key to an integer.
  • Call UserService.get_user_by_id with the database session db and the extracted user_id to retrieve the user.
  • Check if the user object returned from the UserService.get_user_by_id call is None (meaning no user was found).
    • If user is None, raise an HTTPException with a 404 status code and the detail message "User not found".
  • If a user object is successfully retrieved (not None), return this user object.

Usage Tips

  • Always use Depends(get_token) and Depends(get_db) to ensure proper authentication and database session management. This pattern guarantees secure, consistent access to user data across protected routes.

  • Integrate this function as a FastAPI dependency for any endpoint requiring an authenticated user. This simplifies route protection, automatically handling token validation and user retrieval before route execution.

Additional Notes

  • The user_id extraction assumes the sub claim in the token payload is an integer. Ensure get_token consistently provides this format to prevent potential ValueError during conversion.

  • The UserService.get_user_by_id call is critical for database interaction. Performance of this lookup directly impacts API response times, so ensure UserService is optimized for efficient user retrieval.

Routes

GET /search/{search_query}

This route retrieves a paginated list of posts matching a specific search query. It utilizes database session and pagination parameters to efficiently fetch and return relevant post data, ensuring structured `PostResponse` objects.
=== " "

Activity Diagram - "GET /search/{search_query}" /app/routes/posts.pyActivity Diagram - "GET /search/{search_query}"  Inputs: search_query, skip, limitDependency InjectionGet database sessionRetrieve PostsCall PostService.search_posts with database session, query, skip,and limitFormat ResponseInitialize empty list for PostResponse objectsConvert post object to PostResponse formatAdd formatted PostResponse to listFor each post in retrieved postsmore posts?return List of PostResponse objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "GET /search/{search_query}" /app/routes/posts.pyActivity Diagram - "GET /search/{search_query}"  Inputs: search_query, skip, limitDependency InjectionGet database sessionRetrieve PostsCall PostService.search_posts with database session, query, skip,and limitFormat ResponseInitialize empty list for PostResponse objectsConvert post object to PostResponse formatAdd formatted PostResponse to listFor each post in retrieved postsmore posts?return List of PostResponse objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Route diagram - "GET /search/{search_query}" /app/routes/posts.pyRoute diagram - "GET /search/{search_query}"  GET /search/{search_query}Depends()Query()Depends()PostResponse.from_orm()Query()Depends()PostService.search_posts()PostResponse.from_orm()Query()Depends()PostResponse.from_orm()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Route diagram - "GET /search/{search_query}" /app/routes/posts.pyRoute diagram - "GET /search/{search_query}"  GET /search/{search_query}Depends()Query()Depends()PostResponse.from_orm()Query()Depends()PostService.search_posts()PostResponse.from_orm()Query()Depends()PostResponse.from_orm()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "GET /search/{search_query}" Sequence Diagram - "GET /search/{search_query}"  RouterDatabaseDatabasePostServicePostResponseClientRouterDatabasePostServicePostResponseClientClientRouterRouterDatabaseDatabasePostServicePostServicePostResponsePostResponseRouterDatabaseDatabasePostServicePostResponseRequest HandlingGET /search/{search_query}Client sends a search request to the API endpoint.get_db()Router obtains a database session via dependency injection.db_sessionData Retrievalsearch_posts(db_session, search_query, skip, limit)Router delegates the search operation to the PostService.query_posts(search_query, skip, limit)PostService queries the database for posts matching thesearch criteria.list_of_post_orm_objectslist_of_post_orm_objectsPostService returns the raw ORM objects to the Router.Response Serializationloop[For each post_orm_object in list_of_post_orm_objects]from_orm(post_orm_object)Each ORM object is converted into a Pydantic PostResponsemodel.post_response_objectlist_of_PostResponse_objectsRouter returns the list of serialized PostResponse objects tothe Client./app/routes/posts.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "GET /search/{search_query}" Sequence Diagram - "GET /search/{search_query}"  RouterDatabaseDatabasePostServicePostResponseClientRouterDatabasePostServicePostResponseClientClientRouterRouterDatabaseDatabasePostServicePostServicePostResponsePostResponseRouterDatabaseDatabasePostServicePostResponseRequest HandlingGET /search/{search_query}Client sends a search request to the API endpoint.get_db()Router obtains a database session via dependency injection.db_sessionData Retrievalsearch_posts(db_session, search_query, skip, limit)Router delegates the search operation to the PostService.query_posts(search_query, skip, limit)PostService queries the database for posts matching thesearch criteria.list_of_post_orm_objectslist_of_post_orm_objectsPostService returns the raw ORM objects to the Router.Response Serializationloop[For each post_orm_object in list_of_post_orm_objects]from_orm(post_orm_object)Each ORM object is converted into a Pydantic PostResponsemodel.post_response_objectlist_of_PostResponse_objectsRouter returns the list of serialized PostResponse objects tothe Client./app/routes/posts.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Endpoint

GET /search/{search_query}

Handler Input Parameters

  • search_query (str)

    Path parameter string used to filter posts. This value is directly passed to the PostService for database search operations, defining the content to find.

  • skip (int)

    Integer query parameter for pagination, indicating number of items to skip. Defaults to 0, must be non-negative, controlling the result set offset.

  • limit (int)

    Integer query parameter for pagination, specifying maximum items to return. Defaults to 10, between 1 and 100, restricting response size.

  • db (Session)

    Database session dependency injected for performing database operations. This session is crucial for interacting with the PostService layer, managing data persistence.

Request Parameters

  • search_query (str)

    String path parameter for filtering posts. This value is essential for defining the search criteria applied by the PostService, directly influencing results.

  • skip (int)

    Integer query parameter controlling pagination offset. It determines how many initial results are bypassed before fetching the current page, optimizing data retrieval.

  • limit (int)

    Integer query parameter controlling maximum results per page. This parameter ensures that the number of returned posts remains within a defined range, preventing overload.

Response / Output

  • list[PostResponse] (list[PostResponse])

    A list of PostResponse objects, each representing a post matching the search criteria. Each object is converted from an ORM model for consistent output.

Route Logic / Request Processing

  • Receive GET request at /search/{search_query} with path and query parameters.
  • Call PostService.search_posts using injected db session, search_query, skip, and limit parameters.
  • Iterate through each p in the posts list returned from the service call.
  • Convert each p into a PostResponse object using PostResponse.from_orm(p).
  • Return the resulting list of PostResponse objects as the API response.

Usage Tips

  • Always specify skip and limit query parameters for efficient pagination. This prevents large data transfers and improves response times for clients, optimizing user experience.

  • Refine your search_query for precise results. Broad queries might return many irrelevant posts, impacting performance and user experience negatively, so be specific.

Additional Notes

  • The response_model ensures that the returned data strictly conforms to the PostResponse schema. This provides consistent and predictable output for consumers, aiding client-side development.

  • The get_db dependency injection manages database session lifecycle. This ensures proper connection handling and resource management for each request, maintaining application stability.

GET /user/{user_id}

This GET endpoint retrieves a list of posts associated with a specific user ID. It validates the user's existence, fetches paginated posts, and returns them as a list of PostResponse objects.
=== " "

Activity Diagram - "GET /user/{user_id}" /app/routes/posts.pyActivity Diagram - "GET /user/{user_id}"  Inputs: user_id, skip, limit, dbRetrieve user by ID from databaseuser not found?yesnoRaise HTTPException (404, "User not found")Retrieve posts for user from databaseTransform posts to PostResponse objectsreturn List of PostResponse objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "GET /user/{user_id}" /app/routes/posts.pyActivity Diagram - "GET /user/{user_id}"  Inputs: user_id, skip, limit, dbRetrieve user by ID from databaseuser not found?yesnoRaise HTTPException (404, "User not found")Retrieve posts for user from databaseTransform posts to PostResponse objectsreturn List of PostResponse objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Route diagram - "GET /user/{user_id}" /app/routes/posts.pyRoute diagram - "GET /user/{user_id}"  GET /user/{user_id}UserService.get_user_by_id()HTTPException()Depends()Query()Depends()PostResponse.from_orm()Query()Depends()PostResponse.from_orm()Query()Depends()UserService.get_user_by_id()HTTPException()PostService.get_user_posts()PostResponse.from_orm()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Route diagram - "GET /user/{user_id}" /app/routes/posts.pyRoute diagram - "GET /user/{user_id}"  GET /user/{user_id}UserService.get_user_by_id()HTTPException()Depends()Query()Depends()PostResponse.from_orm()Query()Depends()PostResponse.from_orm()Query()Depends()UserService.get_user_by_id()HTTPException()PostService.get_user_posts()PostResponse.from_orm()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "GET /user/{user_id}" Sequence Diagram - "GET /user/{user_id}"  RouteHandlerDatabaseSessionDatabaseSessionUserServicePostServiceClientRouteHandlerDatabaseSessionUserServicePostServicePostResponseClientClientRouteHandlerRouteHandlerDatabaseSessionDatabaseSessionUserServiceUserServicePostServicePostServicePostResponsePostResponseRouteHandlerDatabaseSessionDatabaseSessionUserServicePostServiceRequest HandlingGET /user/{user_id}user_id, skip, limit parameters receivedFetch Userget_user_by_id(db_session, user_id)query(User).filter(User.id == user_id).first()user_recorduserUser Validationalt[User not found]Raise HTTPException(404, "User not found")FastAPI converts HTTPException to HTTP 404 responseHTTP 404 Not Found[User found]User object retrieved successfullyFetch Postsget_user_posts(db_session, user_id, skip, limit)query(Post).filter(Post.user_id ==user_id).offset(skip).limit(limit).all()posts_recordsposts_listTransform Posts to Response Modelloop[For each post in posts_list]from_orm(post)Converts ORM model to Pydantic PostResponsePostResponse_instanceRespond to ClientHTTP 200 OK (list[PostResponse])/app/routes/posts.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "GET /user/{user_id}" Sequence Diagram - "GET /user/{user_id}"  RouteHandlerDatabaseSessionDatabaseSessionUserServicePostServiceClientRouteHandlerDatabaseSessionUserServicePostServicePostResponseClientClientRouteHandlerRouteHandlerDatabaseSessionDatabaseSessionUserServiceUserServicePostServicePostServicePostResponsePostResponseRouteHandlerDatabaseSessionDatabaseSessionUserServicePostServiceRequest HandlingGET /user/{user_id}user_id, skip, limit parameters receivedFetch Userget_user_by_id(db_session, user_id)query(User).filter(User.id == user_id).first()user_recorduserUser Validationalt[User not found]Raise HTTPException(404, "User not found")FastAPI converts HTTPException to HTTP 404 responseHTTP 404 Not Found[User found]User object retrieved successfullyFetch Postsget_user_posts(db_session, user_id, skip, limit)query(Post).filter(Post.user_id ==user_id).offset(skip).limit(limit).all()posts_recordsposts_listTransform Posts to Response Modelloop[For each post in posts_list]from_orm(post)Converts ORM model to Pydantic PostResponsePostResponse_instanceRespond to ClientHTTP 200 OK (list[PostResponse])/app/routes/posts.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Endpoint

GET /user/{user_id}

Handler Input Parameters

  • user_id (int)

    Path parameter identifying the user. Used to fetch user details and their associated posts from the database. This integer value is crucial for targeted data retrieval.

  • skip (int)

    Query parameter for pagination offset. Specifies how many records to skip before starting to return results. Defaults to 0 for initial data fetching.

  • limit (int)

    Query parameter for pagination size. Defines the maximum number of posts to return. Defaults to 10 and is capped at 100 for performance.

  • db (Session)

    Database session dependency. Provides an active database connection for UserService and PostService operations within this request context. Essential for data interaction.

Request Parameters

  • user_id (int)

    Integer path parameter. Identifies the target user whose posts are to be retrieved. Must be a valid integer for database lookup and data fetching.

  • skip (int)

    Integer query parameter. Controls the starting point for fetching posts, ensuring pagination. Must be non-negative, with a default value of 0 for initial requests.

  • limit (int)

    Integer query parameter. Determines the maximum number of posts returned per request. Must be between 1 and 100, defaulting to 10 for efficient data transfer.

Response / Output

  • list[PostResponse] (list[PostResponse])

    A list of PostResponse objects. Each object represents a post belonging to the specified user, formatted for client consumption. This is the successful data payload.

Status Codes & Exceptions

  • 404 Not Found: Returned if the user_id provided in the path does not correspond to an existing user in the database. This indicates an invalid user identifier.
  • 200 OK: Returned upon successful retrieval of user posts. The response body contains a list of PostResponse objects, potentially empty if the user has no posts.

Route Logic / Request Processing

  • Receive GET request for /user/{user_id} with path parameter user_id and optional query parameters skip, limit.
  • Obtain a database session via Depends(get_db).
  • Retrieve user details from the database using UserService.get_user_by_id with the provided user_id.
  • Check if the user object was found.
    • If user is None: raise an HTTPException with 404 status code and detail "User not found".
  • Retrieve posts associated with the user_id from the database using PostService.get_user_posts, applying skip and limit for pagination.
  • Convert each retrieved post object into a PostResponse object using PostResponse.from_orm.
  • Return the list of PostResponse objects.

Usage Tips

  • Always provide a valid user_id in the path to avoid a 404 Not Found error. Utilize skip and limit query parameters for efficient pagination of results.

  • Ensure skip is non-negative and limit is between 1 and 100 to prevent validation errors. Handle empty lists gracefully, as a user might have no posts.

Additional Notes

  • This endpoint relies on UserService and PostService for data access, abstracting database operations. The response_model ensures consistent output formatting for all returned post objects.

  • The HTTPException for 404 is explicitly raised, providing clear error feedback. Pagination parameters offer flexible control over the data retrieval process.

GET /{post_id}

GET /{post_id} retrieves a specific blog post by its unique identifier. It fetches post details, increments its view count, and returns the formatted post data or a 404 error.
=== " "

Activity Diagram - "GET /{post_id}" /app/routes/posts.pyActivity Diagram - "GET /{post_id}"  Inputs: post_id, dbRetrieve post by ID from databasepost not found?yesnoRaise HTTPException (404 Not Found)Increment post view countConvert database post to PostResponse modelreturn PostResponse object   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "GET /{post_id}" /app/routes/posts.pyActivity Diagram - "GET /{post_id}"  Inputs: post_id, dbRetrieve post by ID from databasepost not found?yesnoRaise HTTPException (404 Not Found)Increment post view countConvert database post to PostResponse modelreturn PostResponse object   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Route diagram - "GET /{post_id}" /app/routes/posts.pyRoute diagram - "GET /{post_id}"  GET /{post_id}PostResponse.from_orm()Depends()PostService.get_post_by_id()HTTPException()PostService.increment_view_count()PostResponse.from_orm()Depends()Depends()Depends()PostService.get_post_by_id()HTTPException()PostService.get_post_by_id()HTTPException()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Route diagram - "GET /{post_id}" /app/routes/posts.pyRoute diagram - "GET /{post_id}"  GET /{post_id}PostResponse.from_orm()Depends()PostService.get_post_by_id()HTTPException()PostService.increment_view_count()PostResponse.from_orm()Depends()Depends()Depends()PostService.get_post_by_id()HTTPException()PostService.get_post_by_id()HTTPException()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "GET /{post_id}" Sequence Diagram - "GET /{post_id}"  APIget_post_handlerget_db_dependencyDatabaseSessionDatabaseSessionDatabaseSessionPostServicePostServiceDatabaseDatabaseDatabasePostResponseClientAPIget_post_handlerget_db_dependencyDatabaseSessionPostServiceDatabasePostResponseClientClientAPIAPIget_post_handlerget_post_handlerget_db_dependencyget_db_dependencyDatabaseSessionDatabaseSessionPostServicePostServiceDatabaseDatabasePostResponsePostResponseAPIget_post_handlerget_db_dependencyDatabaseSessionDatabaseSessionDatabaseSessionPostServicePostServiceDatabaseDatabaseDatabasePostResponseRequest HandlingGET /{post_id}get_post(post_id)get_db()Dependency injection provides DB sessiondb_sessionget_post_by_id(db_session, post_id)Fetches post from DB by IDquery(Post).filter(id=post_id).first()SELECT * FROM posts WHERE id = post_idpost_record / Nonedb_post / Nonedb_post / Nonealt[db_post is None]raise HTTPException(404, "Post not found")Post not found, raise 404 exceptionHTTP 404 Not Found[db_post exists]increment_view_count(db_session, post_id)Increments view count and commits to DBget(Post, post_id)SELECT * FROM posts WHERE id = post_idpost_objectpost_objectpost_object.view_count += 1commit()UPDATE posts SET view_count = ... WHERE id = post_idupdate_successcommit_successfrom_orm(db_post)Converts ORM object to Pydantic modelPostResponse_objectPostResponse_objectHTTP 200 OK (PostResponse_object)/app/routes/posts.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "GET /{post_id}" Sequence Diagram - "GET /{post_id}"  APIget_post_handlerget_db_dependencyDatabaseSessionDatabaseSessionDatabaseSessionPostServicePostServiceDatabaseDatabaseDatabasePostResponseClientAPIget_post_handlerget_db_dependencyDatabaseSessionPostServiceDatabasePostResponseClientClientAPIAPIget_post_handlerget_post_handlerget_db_dependencyget_db_dependencyDatabaseSessionDatabaseSessionPostServicePostServiceDatabaseDatabasePostResponsePostResponseAPIget_post_handlerget_db_dependencyDatabaseSessionDatabaseSessionDatabaseSessionPostServicePostServiceDatabaseDatabaseDatabasePostResponseRequest HandlingGET /{post_id}get_post(post_id)get_db()Dependency injection provides DB sessiondb_sessionget_post_by_id(db_session, post_id)Fetches post from DB by IDquery(Post).filter(id=post_id).first()SELECT * FROM posts WHERE id = post_idpost_record / Nonedb_post / Nonedb_post / Nonealt[db_post is None]raise HTTPException(404, "Post not found")Post not found, raise 404 exceptionHTTP 404 Not Found[db_post exists]increment_view_count(db_session, post_id)Increments view count and commits to DBget(Post, post_id)SELECT * FROM posts WHERE id = post_idpost_objectpost_objectpost_object.view_count += 1commit()UPDATE posts SET view_count = ... WHERE id = post_idupdate_successcommit_successfrom_orm(db_post)Converts ORM object to Pydantic modelPostResponse_objectPostResponse_objectHTTP 200 OK (PostResponse_object)/app/routes/posts.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Endpoint

GET /{post_id}

Handler Input Parameters

  • post_id (int)

    This int parameter represents the unique identifier for the desired blog post. It is used to query the database and increment the view count for the specific post.

  • db (Session)

    This Session object provides the database connection for performing operations. It is injected as a dependency to interact with the database for post retrieval and updates.

Request Parameters

  • post_id (int)

    The post_id is an int path parameter. It uniquely identifies the post to be retrieved and viewed. This value is crucial for database lookup operations.

Response / Output

  • PostResponse (PostResponse)

    This PostResponse object represents the successfully retrieved and formatted blog post data. It includes all relevant post details after being fetched from the database.

Status Codes & Exceptions

  • 404 Not Found: This status is returned when no post matching the provided post_id is found in the database. The response detail indicates 'Post not found' to the client.
  • 200 OK: This status is implicitly returned upon successful retrieval and processing of the post. The response body contains the PostResponse object with the requested post data.

Route Logic / Request Processing

  • Retrieve post_id from path and db session from dependency injection.
  • Call PostService.get_post_by_id to fetch the post from the database.
  • Check if the db_post object was found.
    • If db_post is None: Raise an HTTPException with 404 status code and 'Post not found' detail.
  • Call PostService.increment_view_count to increase the view count for the retrieved post_id.
  • Return the db_post object, converted to PostResponse format using from_orm.

Usage Tips

  • Always provide a valid integer post_id in the URL path to successfully retrieve a post. Invalid or non-existent IDs will result in a 404 Not Found error.

  • Expect a PostResponse object on success, containing the post's details. Handle the 404 error gracefully if the requested post does not exist in the system.

Additional Notes

  • This endpoint automatically increments the view count for each successful post retrieval. This provides basic analytics without requiring a separate update call from the client.

  • The response_model=PostResponse ensures the output data conforms to a predefined schema, providing consistent data structure for clients consuming this API endpoint.

FAQs

Why are PostService and UserService used instead of direct database interactions?

Using dedicated service layers like PostService and UserService abstracts business logic from the API, promoting separation of concerns, reusability, and easier testing of core functionalities effectively.

Why is get_current_user implemented as a dependency?

Implementing get_current_user as a dependency ensures that user authentication and retrieval logic is consistently applied across all protected endpoints, simplifying route definitions and promoting reusability.

Why are Pydantic schemas used for request and response models?

Pydantic schemas provide automatic data validation for incoming requests and serialization for outgoing responses, ensuring data integrity, clear API contracts, and reducing boilerplate code significantly.

Why is PostService.increment_view_count called within the get_post endpoint?

The increment_view_count call within get_post ensures that each successful retrieval of a post automatically updates its view count, reflecting real-time engagement metrics for content popularity.

Insights

Metric Score Level
Complexity 1.00 Very Complex
Security 0.80 Secure
Performance 0.60 Acceptable Performance

Complexity

Low - Repetitive Error Handling

The try-except blocks for HTTPException with 500_INTERNAL_SERVER_ERROR are repeated across multiple routes. A centralized error handler could reduce duplication and improve maintainability.

Security

Medium - Missing Rate Limiting

There is no explicit rate limiting implemented on any endpoints. This could leave the API vulnerable to brute-force attacks or denial-of-service attempts, impacting stability.

Performance

Medium - Synchronous Database Operations

All database operations are synchronous, potentially blocking the event loop under heavy load. Migrating to async/await with an async ORM could improve concurrency significantly.

Medium - Write Operation on Read Endpoint

Incrementing view_count within the get_post endpoint performs a write operation on a read path. This could introduce contention and performance overhead under high traffic.