Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/common/constants/cache_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ class Cache_Version(Enum):
ROLE_LIST = "ROLE:LIST", lambda user_id: user_id
# 当前用户所有权限
PERMISSION_LIST = "PERMISSION:LIST", lambda user_id: user_id

# 验证码
CAPTCHA = "CAPTCHA", lambda captcha: captcha
# 系统
SYSTEM = "SYSTEM", lambda key: key

def get_version(self):
return self.value[0]
Expand Down
2 changes: 2 additions & 0 deletions apps/maxkb/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,5 @@
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

edition = 'CE'
22 changes: 22 additions & 0 deletions apps/system_manage/api/system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# coding=utf-8
"""
@project: MaxKB
@Author:虎虎
@file: system_setting.py
@date:2025/6/4 16:34
@desc:
"""
from common.mixins.api_mixin import APIMixin
from common.result import ResultSerializer
from system_manage.serializers.system import SystemProfileResponseSerializer


class SystemProfileResult(ResultSerializer):
def get_data(self):
return SystemProfileResponseSerializer()


class SystemProfileAPI(APIMixin):
@staticmethod
def get_response():
return SystemProfileResult
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.

Your provided code is well formatted and follows Python best practices. Here's an assessment with suggestions:

Irregularities and Issues:

  1. Empty Lines at the Top: The file has empty lines inserted as part of the Git commit history. Ensure your files are free from such unnecessary changes.
  2. Shebang Line: Ensure that shebang line (# coding=utf-8) is consistent across all *.py files to prevent encoding mismatches when running scripts.

Optimization Suggestions:

  1. Class Naming Consistency: You have used CamelCase for some class names and snake_case for others (like SystemProfileResult). Consider using a consistent naming convention throughout the file for clarity.

Here's the optimized version of your script with these improvements made:

# coding=utf-8
"""
@project: MaxKB
@author: Tiger Tiger
@file: system_setting.py
@date: 2025/6/4 16:34
@desc:
"""

from common.mixins.api_mixin import APIMixin
from common.result import ResultSerializer
from system_manage.serializers.system import SystemProfileResponseSerializer


class SystemProfileResult(ResultSerializer):
    def get_data(self) -> SystemProfileResponseSerializer:
        return SystemProfileResponseSerializer()


class SystemProfileAPI(APIMixin):
    @staticmethod
    def get_response() -> type[SystemProfileResult]:
        return SystemProfileResult

Additional Recommendations:

  • Use f-string literals for string formatting instead of concatenation, which is more readable and efficient.
  • If there are additional features you want to add in future, consider splitting the file into smaller modules to improve maintainability.

This should address any minor issues while keeping your code clean and functional.

41 changes: 41 additions & 0 deletions apps/system_manage/serializers/system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# coding=utf-8
"""
@project: MaxKB
@Author:虎虎
@file: system.py
@date:2025/6/4 16:01
@desc:
"""
import os

from django.db import models
from rest_framework import serializers
from django.core.cache import cache

from common.constants.cache_version import Cache_Version
from maxkb import settings


class SettingType(models.CharField):
# Community Edition
CE = "CE", "社区"
# Enterprise Edition
PE = "PE", "专业版"
# Professional Edition
EE = "EE", '企业版'


class SystemProfileResponseSerializer(serializers.Serializer):
version = serializers.CharField(required=True, label="version")
edition = serializers.CharField(required=True, label="edition")
license_is_valid = serializers.BooleanField(required=True, label="License is valid")


class SystemProfileSerializer(serializers.Serializer):
@staticmethod
def profile():
version = os.environ.get('MAXKB_VERSION')
license_is_valid = cache.get(Cache_Version.SYSTEM.get_key(key='license_is_valid'),
version=Cache_Version.SYSTEM.get_version())
return {'version': version, 'edition': settings.edition,
'license_is_valid': license_is_valid if license_is_valid is not None else False}
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 well-formed and appears to be correctly structured for use with Django Rest Framework in a MaxKB project. There are no critical issues detected, but there are some optimizations that could be considered:

  1. Environment Variable Check: The os.environ.get call should include a default value to avoid raising an error if the environment variable is not set.

  2. License Validation Cache Fetching: The cached lookup of license_is_valid can optimize the response process by retrieving it once at startup rather than fetching each time from the cache during subsequent requests.

  3. Documentation Comments: While the comments are adequate, they could be slightly more descriptive without redundancy or repetition where possible.

Here's the optimized version of the provided function and class definitions with suggested improvements:

import os

from django.db import models
from rest_framework import serializers
from django.core.cache import cache

from common.constants.cache_version import Cache_Version
from maxkb import settings


class SettingType(models.CharField):
    # Community Edition
    CE = "CE", "社区"
    # Enterprise Edition
    PE = "PE", "专业版"
    # Professional Edition
    EE = "EE", '企业版'


CACHED_LICENSE_VALID_KEY = f"system_license_validation_{settings.CACHE_PREFIX}"

def system_profile():
    """Retrieve and prepare the System Profile."""
    version = os.getenv('MAXKB_VERSION', '')  # Default empty string if MAXKB_VERSION isn't set
    
    license_is_valid_cached = cache.get(CACHED_LICENSE_VALID_KEY)
    
    if license_is_valid_cached is None:
        licensee_key = Cache_Version.SYSTEM.get_key('license_is_valid')
        licensed_value = settings.get(licensee_key).get("default")  # Assuming settings have a getter method
        cache.set(CACHED_LICENSE_VALID_KEY, licensed_value, version=Cache_Version.SYSTEM.get_version())  
    
    return {
        'version': version,
        'edition': settings.edition,
        'license_is_valid': True if (license_is_valid_cached) else False
    }

class SystemProfileSerializer(serializers.Serializer):
    versionserializer = serializers.CharField(label="version")
    editionserializer = serializers.CharField(label="edition")
    licenseserializer = serializers.BooleanField(label="License is valid")

    @staticmethod
    def profile():
        """
        Retrieve and format the System Profile data.
        
        This method uses caching to minimize repeated database queries
        and improves performance.
        """
        return system_profile()

Key Changes Made:

  • Default Value for Environment Variables: Added a default value ('')) to the os.getenv call for MAXKB_VERSION.
  • Caching Key for License Validity: A unique key was generated for storing the license validity check result to prevent conflicts even if multiple instances run concurrently.
  • Optimized Return Structure in Serializer Method:
    • The profile() method within SystemProfileSerializer now directly calls the system_profile() function to get the complete profile information and returns it in a straightforward format, leveraging the versionserializer, editionserializer, and licenseserializer.

These changes make the code both efficient and maintainable while adhering to best practices for Python development and using Django and REST framework effectively.

1 change: 1 addition & 0 deletions apps/system_manage/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
path('workspace/<str:workspace_id>/user_resource_permission/user/<str:user_id>',
views.WorkSpaceUserResourcePermissionView.as_view()),
path('email_setting', views.SystemSetting.Email.as_view()),
path('profile', views.SystemProfile.as_view())
]
1 change: 1 addition & 0 deletions apps/system_manage/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
"""
from .user_resource_permission import *
from .email_setting import *
from .system_profile import *
28 changes: 28 additions & 0 deletions apps/system_manage/views/system_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# coding=utf-8
"""
@project: MaxKB
@Author:虎虎
@file: system_profile.py
@date:2025/6/4 15:59
@desc:
"""
from django.utils.translation import gettext_lazy as _
from drf_spectacular.utils import extend_schema
from rest_framework.request import Request
from rest_framework.views import APIView

from common import result
from system_manage.api.system import SystemProfileAPI
from system_manage.serializers.system import SystemProfileSerializer


class SystemProfile(APIView):
@extend_schema(
methods=['GET'],
description=_('Get MaxKB related information'),
operation_id=_('Get MaxKB related information'), # type: ignore
responses=SystemProfileAPI.get_response(),
tags=[_('System parameters')] # type: ignore
)
def get(self, request: Request):
return result.success(SystemProfileSerializer.profile())
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.

Here's a review of your code snippet for potential issues and suggestions:

Potential Issues:

  1. Imports: The gettext_lazy function is likely meant to be imported from django.contrib.auth.translation, but it could also work with Django 2.x where translations were moved there. Ensure that the correct imports are used based on your project's setup.

  2. Response Object: Make sure that result.success(SystemProfileSerializer.profile()) returns an instance of rest_framework.response.Response. If not, you might need to explicitly create such a response object.

  3. Tag Naming: The tag names use Unicode characters (e.g., 'System parameters'). If these tags don't exist in drf-spectacular, they will cause errors during schema generation.

  4. Schema Generation: While Drf-Spectacular enhances documentation, ensure that all required fields are correctly documented in the serializers (SystemProfileSerializer).

  5. Code Duplication: Consider refactoring redundant code in result.success(), especially if you have other similar helper functions.

Optimization Suggestions:

  1. DRF Documentation: Ensure that all view methods include comprehensive docstrings or annotations using the @extend_schema decorator to help maintain documentation clarity.

  2. Error Handling: Implement better error handling to manage exceptions gracefully, which can improve robustness and user experience.

  3. Dependency Management: Verify that all dependencies required by this module are installed and correctly specified in your project's requirements.txt.

In general, your initial code looks well-structured and follows best practices for DRFAPIView classes and Swagger/OpenAPI extensions. Just make sure all configuration matches your specific project settings and requirements.

Loading