Coverage for src/backend/InvenTree/plugin/base/ui/api.py: 40%
36 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
1"""API for UI plugins."""
3from django.urls import path
5from drf_spectacular.utils import extend_schema
6from rest_framework.response import Response
7from rest_framework.views import APIView
9import InvenTree.permissions
10import plugin.base.ui.serializers as UIPluginSerializers
11from common.settings import get_global_setting
12from InvenTree.exceptions import log_error
13from plugin import PluginMixinEnum, registry
16class PluginUIFeatureList(APIView):
17 """API endpoint for listing all available plugin ui features."""
19 permission_classes = [InvenTree.permissions.IsAuthenticatedOrReadScope]
20 serializer_class = UIPluginSerializers.PluginUIFeatureSerializer
22 @extend_schema(
23 responses={200: UIPluginSerializers.PluginUIFeatureSerializer(many=True)}
24 )
25 def get(self, request, feature):
26 """Show available plugin ui features."""
27 features = []
29 if get_global_setting('ENABLE_PLUGINS_INTERFACE'): 29 ↛ 31line 29 didn't jump to line 31 because the condition on line 29 was never true
30 # Extract all plugins from the registry which provide custom ui features
31 for _plugin in registry.with_mixin(
32 PluginMixinEnum.USER_INTERFACE, active=True
33 ):
34 # Allow plugins to fill this data out
36 try:
37 plugin_features = _plugin.get_ui_features(
38 feature, request.query_params, request
39 )
40 except Exception:
41 # Custom features could not load for this plugin
42 # Log the error and continue
43 log_error('get_ui_features', plugin=_plugin.slug)
44 continue
46 if plugin_features and type(plugin_features) is list:
47 for _feature in plugin_features:
48 try:
49 # Ensure that the required fields are present
50 _feature['plugin_name'] = _plugin.slug
51 _feature['feature_type'] = str(feature)
53 # Ensure base fields are strings
54 for field in ['key', 'title', 'description', 'source']:
55 if field in _feature:
56 _feature[field] = str(_feature[field])
58 # Add the feature to the list (serialize)
59 features.append(
60 UIPluginSerializers.PluginUIFeatureSerializer(
61 _feature, many=False
62 ).data
63 )
65 except Exception:
66 # Custom features could not load
67 # Log the error and continue
68 log_error('get_ui_features', plugin=_plugin.slug)
69 continue
71 return Response(features)
74ui_plugins_api_urls = [
75 path(
76 'features/<str:feature>/',
77 PluginUIFeatureList.as_view(),
78 name='api-plugin-ui-feature-list',
79 )
80]