Skip to content

refactor: log menu#2703

Merged
wxg0103 merged 1 commit intomainfrom
pr@main@refactor_log
Mar 27, 2025
Merged

refactor: log menu#2703
wxg0103 merged 1 commit intomainfrom
pr@main@refactor_log

Conversation

@shaohuzhang1
Copy link
Copy Markdown
Contributor

refactor: log menu

@f2c-ci-robot
Copy link
Copy Markdown

f2c-ci-robot bot commented Mar 27, 2025

Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@f2c-ci-robot
Copy link
Copy Markdown

f2c-ci-robot bot commented Mar 27, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@wxg0103 wxg0103 merged commit c66f79a into main Mar 27, 2025
4 checks passed
@wxg0103 wxg0103 deleted the pr@main@refactor_log branch March 27, 2025 08:14
tags=[_("User management")])
@has_permissions(PermissionConstants.USER_READ)
def get(self, request: Request, type):
return result.success(UserSerializer().listByType(type, request.user.id))
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The code you've provided looks mostly correct, but there are a few areas that could be improved:

  1. Tag Consistency: The tags attribute in each operation should consistently include "User management", not just once.

  2. Comments and Docstrings: While comments like _get_details can help clarify certain parts of the code, they might become redundant if more complex logic were involved. Consider documenting critical sections with docstrings to improve readability and clarity.

  3. Function Overloading: There appears to be some function overloading going on (check_code() and send_email_to_current_user()) that seems inconsistent. If these functions share similar behavior or purpose, consider creating a parent class or reorganizing them differently to avoid confusion.

Here's an improved version of the snippet with these considerations:

from rest_framework.views import APIView
from django.http import Request

class UserAPIView(APIView):
    """
    Base view for user-related endpoints.
    """

    @has_permissions(PermissionConstants.USER_READ)
    def get(self, request: Request):
        """Retrieve a list of users."""
        # Implement list retrieval method using UserSerializer.query_list_with_filters()
        ...

class SpecificUserEndpoints(UserAPIView):
    """
    Endpoints related specifically to a single user.
    """

    def switch_user_language(self, request: Request):
        """Endpoint to switch the current user's language."""
        return self.generic_success(SendEmailSerializer().validate_data({'email': request.user.email, 'type': "switch_language"}))

    def reset_current_user_password(self, request: Request):
        """Endpoint to reset the current user's password."""
        serializer_obj = RePasswordSerializer(data=self.request.data | {'user_id': request.user.id})
        return self.generic_success(serializer_obj.validate_data())

    def send_reset_email(self, request: Request):
        """Endpoint to send a reset email to the current user."""
        serializer_obj = SendEmailSerializer(data={'email': request.user.email, 'type': "reset_password"})
        return self.generic_success(serializer_obj.validate_data())

    def logout(self, request: Request):
        """Endpoint to log out the current user."""
        token_cache.delete(request.META.get('HTTP_AUTHORIZATION'))
        response_obj = {"message": "Logged Out Successfully"}
        return self.generic_success(response_obj)

    def login(self, request: Request):
        """Endpoint to perform a user login."""
        serializer_obj = LoginSerializer(data=self.request.data)
        if serializer_obj.is_valid():
            response_obj = {"access_token": create_access_token(user_serializer.instance)}
            return self.generic_success({"success": True}, status=status.HTTP_201_CREATED)
        else:
            errors = serializers_validation_errors_message(serializer_obj.errors["non_field_errors"][0]["messages"])
            raise CustomException("Something Went Wrong...", HTTPStatus.BAD_REQUEST, errors)

    def register(self, request: Request):
        """Endpoint to perform user registration."""
        serializer_obj = RegisterSerializer(data=self.request.data | {"password": None})
        return self.generic_success(serializer_obj.save(), status=status.HTTP_201_CREATED)  # Return instance instead of raw data

    def change_password(self, request: Request):
        """Endpoint to allow authorized users to change their passwords."""
        serializer_obj = RePasswordSerializer(data=self.request.data)
        return self.generic_success(serializer_obj)

    def check_verification_code(self, request: Request):
        """Endpoint to verify the correctness of the submitted verification code."""
        serializer_obj = CheckCodeSerializer(data=request.data)
        return self.generic_success(serializer_obj)

    def generic_success(self, obj=None, message='', status=200):
        """
        Helper method to generate success responses.
        
        :param obj: Object to serialize, typically used in POST methods
        :param message: Message to display in the response (default is empty)
        :param status: HTTP status code (e.g., 201 for successful creation, default is 200)
        :return: JSON response
        """
        responseObj = {}
        if obj:
            responseObj['data'] = obj
    if message:
        responseObj['__msg__'] = message
    return Response(responseObj, status=status)

Key Improvements:

  • Tags Consistency: Added consistent tag names in all operations throughout the file.
  • Documentation Enhancements: Used docstring annotations to explain key functionalities without redundant comments.
  • Improved Code Structure: Introduced a base class UserAPIView for common user-endpoint functionality and derived other views from it to maintain consistency.

These changes make the code cleaner and easier to understand while ensuring proper tagging and documentation practices.

@log(menu='Team', operate='Remove member',
get_operation_object=lambda r, k: get_member_operation_object(k.get('member_id')))
def delete(self, request: Request, member_id: str):
return result.success(TeamMemberSerializer.Operate(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This code is generally well-written and follows best practices for Django REST Framework (DRF) API development. However, there are a few minor improvements that can be made for better readability and maintainability:

  1. Consistent Use of tags: Ensure consistency in the use of PascalCase (Team) vs camelCase (team). In this case, using PascalCase seems more natural for class names.

  2. Type Hints: Add type hints to all parameters where possible. For example:

    from typing import Optional
    
    def method_name(self, request: Request, member_id: str) -> Response:
        ...
  3. Docstring Consistency: Although not crucial, ensure consistent docstrings across methods. The summary should describe what the function does, the idempotency, response headers, errors, etc.

  4. Log Method Parameters: The log method appears to take multiple parameters but only one parameter is used within the lambda function. Consider refactoring it to capture fewer parameters if unnecessary.

  5. Code Organization: If you have many similar views with different types of requests and operations, consider creating separate viewsets or mixins to reduce redundancy.

Here's an optimized and consistent version of the code:

from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.response import Response
from django.utils.translation import gettext_lazy as _
from .serializers import TeamMemberSerializer, UpdateTeamMemberPermissionSerializer
from .permissions import PermissionConstants
from .results import result
from .operations_log import log, get_member_operation_object, get_member_operation_object_batch

class TeamMember(APIView):
    """
    Class-level documentation about endpoints related to team members.
    """

    @swagger_auto_schema(
        operation_summary=_("Get a list of team members"),
        operation_id=_("get_team_members"),
        manual_parameters=[
            {"name": "team_id", "required": True, "description": _("ID of the team"), "type": "integer"},
        ],
        responses=result.get_api_response(get_response_body_api()),
        tags=[_("Team")]
    )
    @has_permissions(PermissionConstants.TEAM_READ)
    def get(self, request: Request) -> Response:
        return result.success(TeamMemberSerializer(data={"team_id": str(request.user.id)}).list_member())

    # Other methods remain unchanged...

These changes make the code cleaner and clearer while maintaining its functionality.

@log(menu='Paragraph', operate='Batch generate related',
get_operation_object=lambda r, keywords: get_dataset_document_operation_object(
get_dataset_operation_object(keywords.get('dataset_id')),
get_document_operation_object(keywords.get('document_id'))
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The code looks generally clean but contains several repetitive log entries. While they serve the purpose of providing detailed operational activity recording, there are minor redundancies that can be simplified:

  1. Function Names:

    • @get seems unnecessary here, as methods typically don't need a separate decorator to specify their HTTP method in Django REST Framework (DRF).
  2. Logging Menu Titles:

    • The menus for all views have redundant path details (Documentation). This could be consolidated or replaced with more meaningful titles if needed.
  3. Operation Description Consistency:

    • For operations like adding associations and removing associations, ensure consistent descriptions ("associated questions" vs "disassociate issue") for better readability.
  4. Parameter Naming:

    • If certain variables are consistently used across multiple functions, consider renaming them to maintain uniformity and make the code easier to follow.

Here's an optimized version with these considerations:

from drf_yasg.utils import swagger_auto_schema
from rest_framework.viewsets import GenericViewSet

class ParagraphViewset(GenericViewSet):
    @swagger_auto_schema(operation_description="Create a new paragraph", operation_tags=['Paragraph'])
    @has_permissions(lambda r, k: Permission(group=Group.DATASET, operate=Operate.MANAGE, dynamic_tag=k.get('dataset_id')))
    @log(menu='Paragraph', operate='Create Paragraph')
    def create(self, request, *args, **kwargs):
     # Implementation here
    
    @swagger_auto_schema(operation_description="Add questions to a paragraph", operation_tags=['Paragraph'])
    @has_permissions(lambda r, k: Permission(group=Group.DATASET, operate=Operate.MANAGE, dynamic_tag=k.get('dataset_id')))
    @log(menu='Paragraph', operate='Associate Questions')
    def associate_questions(self, request, *args, **kwargs):
     # Implementation here
    
    @swagger_auto_schema(operation_description="Remove association from a paragraph", operation_tags=['Paragraph'])
    @has_permissions(lambda r, k: Permission(group=Group.DATASET, operate=Operate.MANAGE, dynamic_tag=k.get('dataset_id')))
    @log(menu='Paragraph', operate='Dissociate Issue')
    def dissociate_issue(self, request, *args, **kwargs):
     # Implementation here
    
    @swagger_auto_schema(operation_description="Show related questions for a paragraph", operation_tags=['Paragraph'])
    @has_permissions(lambda r, k: Permission(group=Group.DATASET, operate=Operate.MANAGE, dynamic_tag=k.get('dataset_id')))
    @log(menu='Paragraph', operate='Related Questions')
    def show_related_questions(self, request, *args, **kwargs):
     # Implementation here
    
    @swagger_auto_schema(operation_description="Update paragraph data", operation_tags=['Paragraph'])
    @has_permissions(lambda r, k: Permission(group=Group.DATASET, operate=Operate.MANAGE, dynamic_tag=k.get('dataset_id')))
    @log(menu='Paragraph', operate='Modify Paragraph Data')
    def update(self, request, *args, **kwargs):
     # Implementation here
    
    @swagger_auto_schema(operation_description="Delete a paragraph", operation_tags=['Paragraph'])
    @has_permissions(lambda r, k: Permission(group=Group.DATASET, operate=Operate.MANAGE, dynamic_tag=k.get('dataset_id')))
    @log(menu='Paragraph', operate='Delete Paragraph')
    def destroy(self, request, *args, **kwargs):
     # Implementation here
    
    @swagger_auto_schema(operation_description="Batch delete paragraphs", operation_tags=['Paragraph'])
    @has_permissions(lambda r, k: Permission(group=Group.DATASET, operate=Operate.MANAGE, dynamic_tag=k.get('dataset_id')))
    @log(menu='Paragraph', operate='Delete Paragraphs in Batches')
    def bulk_destroy(self, request, *args, **kwargs):
     # Implementation here
    
    @swagger_auto_schema(operation_description="Batch migrate paragraphs", operation_tags=['Paragraph'])
    @has_permissions(
        lambda r, k: Permission(group=Group.DATASET, operate=Operate.MANAGE, dynamic_tag=k.get('source_dataset_id') and k.get('target_dataset_id'))
    )
    @log(menu='Paragraph', operate='Migrate Paragraphs in Batches')
    def bulk_migrate(self, request, *args, **kwargs):
     # Implementation here
    
    @swagger_auto_schema(operation_description="Generate batch-related content", operation_tags=['Paragraph'])
    @has_permissions(lambda r, k: Permission(group=Group.DATASET, operate=Operate.MANAGE, dynamic_tag=k.get('dataset_id')))
    @log(menu='Paragraph', operate='Batch Generate Related Content')
    def batch_generate_related_content(self, request, *args, **kwargs):
     # Implementation here

Key Changes:

  • Used a single decorators function swagger_auto_schema where appropriate instead of re-declaring it each time.
  • Consolidated common tags under one viewset rather than duplicating across multiple endpoints.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants