mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Expose API version descriptors for admins via API (#5865)
* Added endpoint to expose API version descriptors for admins * Refactored tests and moved them to seperate file * Switched to raw string * add coverage exclusion * ignore imports (possible fix to multiline imports) * Add OpenApi Schema * removed changes regarding coverage * moved new functions to `version` to keep api_version a pure static file * clean up diff
This commit is contained in:
parent
0af08da6f8
commit
c34e14baec
@ -6,7 +6,8 @@ from django.http import JsonResponse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django_q.models import OrmQ
|
||||
from rest_framework import permissions
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
||||
from rest_framework import permissions, serializers
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.serializers import ValidationError
|
||||
from rest_framework.views import APIView
|
||||
@ -21,8 +22,9 @@ from plugin.serializers import MetadataSerializer
|
||||
from users.models import ApiToken
|
||||
|
||||
from .email import is_email_configured
|
||||
from .mixins import RetrieveUpdateAPI
|
||||
from .mixins import ListAPI, RetrieveUpdateAPI
|
||||
from .status import check_system_health, is_worker_running
|
||||
from .version import inventreeApiText
|
||||
from .views import AjaxView
|
||||
|
||||
|
||||
@ -57,6 +59,34 @@ class VersionView(APIView):
|
||||
})
|
||||
|
||||
|
||||
class VersionSerializer(serializers.Serializer):
|
||||
"""Serializer for a single version."""
|
||||
version = serializers.CharField()
|
||||
date = serializers.CharField()
|
||||
gh = serializers.CharField()
|
||||
text = serializers.CharField()
|
||||
latest = serializers.BooleanField()
|
||||
|
||||
class Meta:
|
||||
"""Meta class for VersionSerializer."""
|
||||
fields = ['version', 'date', 'gh', 'text', 'latest']
|
||||
|
||||
|
||||
class VersionApiSerializer(serializers.Serializer):
|
||||
"""Serializer for the version api endpoint."""
|
||||
VersionSerializer(many=True)
|
||||
|
||||
|
||||
class VersionTextView(ListAPI):
|
||||
"""Simple JSON endpoint for InvenTree version text."""
|
||||
permission_classes = [permissions.IsAdminUser]
|
||||
|
||||
@extend_schema(responses={200: OpenApiResponse(response=VersionApiSerializer)})
|
||||
def list(self, request, *args, **kwargs):
|
||||
"""Return information about the InvenTree server."""
|
||||
return JsonResponse(inventreeApiText())
|
||||
|
||||
|
||||
class InfoView(AjaxView):
|
||||
"""Simple JSON endpoint for InvenTree information.
|
||||
|
||||
|
@ -3,10 +3,9 @@
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 148
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
"""
|
||||
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
v148 -> 2023-11-06 : https://github.com/inventree/InvenTree/pull/5872
|
||||
- Allow "quantity" to be specified when installing an item into another item
|
||||
|
||||
@ -115,7 +114,7 @@ v117 -> 2023-05-22 : https://github.com/inventree/InvenTree/pull/4854
|
||||
v116 -> 2023-05-18 : https://github.com/inventree/InvenTree/pull/4823
|
||||
- Updates to part parameter implementation, to use physical units
|
||||
|
||||
v115 - > 2023-05-18 : https://github.com/inventree/InvenTree/pull/4846
|
||||
v115 -> 2023-05-18 : https://github.com/inventree/InvenTree/pull/4846
|
||||
- Adds ability to partially scrap a build output
|
||||
|
||||
v114 -> 2023-05-16 : https://github.com/inventree/InvenTree/pull/4825
|
||||
|
41
InvenTree/InvenTree/test_api_version.py
Normal file
41
InvenTree/InvenTree/test_api_version.py
Normal file
@ -0,0 +1,41 @@
|
||||
"""Tests for api_version."""
|
||||
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
from InvenTree.api_version import INVENTREE_API_VERSION
|
||||
from InvenTree.unit_test import InvenTreeAPITestCase
|
||||
from InvenTree.version import inventreeApiText, parse_version_text
|
||||
|
||||
|
||||
class ApiVersionTests(InvenTreeAPITestCase):
|
||||
"""Tests for api_version functions and APIs."""
|
||||
|
||||
def test_api(self):
|
||||
"""Test that the API text is correct."""
|
||||
url = reverse('api-version-text')
|
||||
response = self.client.get(url, format='json')
|
||||
data = response.json()
|
||||
|
||||
self.assertEqual(len(data), 10)
|
||||
|
||||
def test_inventree_api_text(self):
|
||||
"""Test that the inventreeApiText function works expected."""
|
||||
# Normal run
|
||||
resp = inventreeApiText()
|
||||
self.assertEqual(len(resp), 10)
|
||||
|
||||
# More responses
|
||||
resp = inventreeApiText(20)
|
||||
self.assertEqual(len(resp), 20)
|
||||
|
||||
# Specific version
|
||||
resp = inventreeApiText(start_version=5)
|
||||
self.assertEqual(list(resp)[0], 'v5')
|
||||
|
||||
def test_parse_version_text(self):
|
||||
"""Test that api version text is correctly parsed."""
|
||||
resp = parse_version_text()
|
||||
|
||||
# Check that all texts are parsed
|
||||
self.assertEqual(len(resp), INVENTREE_API_VERSION - 1)
|
@ -36,7 +36,8 @@ from plugin.urls import get_plugin_urls
|
||||
from stock.urls import stock_urls
|
||||
from web.urls import urlpatterns as platform_urls
|
||||
|
||||
from .api import APISearchView, InfoView, NotFoundView, VersionView
|
||||
from .api import (APISearchView, InfoView, NotFoundView, VersionTextView,
|
||||
VersionView)
|
||||
from .magic_login import GetSimpleLoginView
|
||||
from .social_auth_urls import (EmailListView, EmailPrimaryView,
|
||||
EmailRemoveView, EmailVerifyView,
|
||||
@ -79,6 +80,7 @@ apipatterns = [
|
||||
re_path('schema/', SpectacularAPIView.as_view(custom_settings={'SCHEMA_PATH_PREFIX': '/api/'}), name='schema'),
|
||||
|
||||
# InvenTree information endpoints
|
||||
path("version-text", VersionTextView.as_view(), name="api-version-text"), # version text
|
||||
path('version/', VersionView.as_view(), name='api-version'), # version info
|
||||
path('', InfoView.as_view(), name='api-inventree-info'), # server info
|
||||
|
||||
|
@ -16,7 +16,7 @@ from django.conf import settings
|
||||
|
||||
from dulwich.repo import NotGitRepository, Repo
|
||||
|
||||
from .api_version import INVENTREE_API_VERSION
|
||||
from .api_version import INVENTREE_API_TEXT, INVENTREE_API_VERSION
|
||||
|
||||
# InvenTree software version
|
||||
INVENTREE_SW_VERSION = "0.13.0 dev"
|
||||
@ -142,6 +142,52 @@ def inventreeApiVersion():
|
||||
return INVENTREE_API_VERSION
|
||||
|
||||
|
||||
def parse_version_text():
|
||||
"""Parse the version text to structured data."""
|
||||
patched_data = INVENTREE_API_TEXT.split("\n\n")
|
||||
# Remove first newline on latest version
|
||||
patched_data[0] = patched_data[0].replace("\n", "", 1)
|
||||
|
||||
version_data = {}
|
||||
for version in patched_data:
|
||||
data = version.split("\n")
|
||||
|
||||
version_split = data[0].split(' -> ')
|
||||
version_detail = version_split[1].split(':', 1) if len(version_split) > 1 else ['', ]
|
||||
new_data = {
|
||||
"version": version_split[0].strip(),
|
||||
"date": version_detail[0].strip(),
|
||||
"gh": version_detail[1].strip() if len(version_detail) > 1 else None,
|
||||
"text": data[1:],
|
||||
"latest": False,
|
||||
}
|
||||
version_data[new_data["version"]] = new_data
|
||||
return version_data
|
||||
|
||||
|
||||
INVENTREE_API_TEXT_DATA = parse_version_text()
|
||||
"""Pre-processed API version text."""
|
||||
|
||||
|
||||
def inventreeApiText(versions: int = 10, start_version: int = 0):
|
||||
"""Returns API version descriptors.
|
||||
|
||||
Args:
|
||||
versions: Number of versions to return. Default: 10
|
||||
start_version: first version to report. Defaults to return the latest {versions} versions.
|
||||
"""
|
||||
version_data = INVENTREE_API_TEXT_DATA
|
||||
|
||||
# Define the range of versions to return
|
||||
if start_version == 0:
|
||||
start_version = INVENTREE_API_VERSION - versions
|
||||
|
||||
return {
|
||||
f"v{a}": version_data.get(f"v{a}", None)
|
||||
for a in range(start_version, start_version + versions)
|
||||
}
|
||||
|
||||
|
||||
def inventreeDjangoVersion():
|
||||
"""Returns the version of Django library."""
|
||||
return django.get_version()
|
||||
|
Loading…
Reference in New Issue
Block a user