Get rids of the APIEndPoint and APIResource classes. Register API url using the 'has_rest_api' AppConfig variable.

Signed-off-by: Michael Price <loneviking72@gmail.com>
This commit is contained in:
Michael Price
2018-03-04 04:21:29 -04:00
committed by Roberto Rosario
parent 36d19ea284
commit e1956f8d80
26 changed files with 39 additions and 197 deletions

View File

@@ -4,12 +4,12 @@ from django.utils.translation import ugettext_lazy as _
from common import MayanAppConfig, menu_object, menu_sidebar
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .links import link_acl_create, link_acl_delete, link_acl_permissions
class ACLsApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'acls'
verbose_name = _('ACLs')
@@ -17,8 +17,6 @@ class ACLsApp(MayanAppConfig):
def ready(self):
super(ACLsApp, self).ready()
APIEndPoint(app=self, version_string='1')
AccessControlList = self.get_model('AccessControlList')
SourceColumn(

View File

@@ -11,7 +11,6 @@ from common import (
)
from documents.search import document_page_search, document_search
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .links import (
link_cabinet_list, link_document_cabinet_list,
@@ -31,6 +30,7 @@ from .widgets import widget_document_cabinets
class CabinetsApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'cabinets'
verbose_name = _('Cabinets')
@@ -46,8 +46,6 @@ class CabinetsApp(MayanAppConfig):
DocumentCabinet = self.get_model('DocumentCabinet')
Cabinet = self.get_model('Cabinet')
APIEndPoint(app=self, version_string='1')
# Add explicit order_by as DocumentCabinet ordering Meta option has no
# effect.
Document.add_to_class(

View File

@@ -13,7 +13,6 @@ from common import MayanAppConfig, menu_facet, menu_main, menu_sidebar
from common.dashboards import dashboard_main
from events import ModelEventType
from mayan.celery import app
from rest_api.classes import APIEndPoint
from .dashboard_widgets import widget_checkouts
from .events import (
@@ -36,6 +35,7 @@ from .tasks import task_check_expired_check_outs # NOQA
class CheckoutsApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'checkouts'
verbose_name = _('Checkouts')
@@ -43,8 +43,6 @@ class CheckoutsApp(MayanAppConfig):
def ready(self):
super(CheckoutsApp, self).ready()
APIEndPoint(app=self, version_string='1')
Document = apps.get_model(
app_label='documents', model_name='Document'
)

View File

@@ -15,7 +15,6 @@ from django.utils.translation import ugettext_lazy as _
from mayan.celery import app
from navigation.classes import Separator, Text
from rest_api.classes import APIEndPoint
from .handlers import (
handler_pre_initial_setup, handler_pre_upgrade,
@@ -75,6 +74,7 @@ class MayanAppConfig(apps.AppConfig):
class CommonApp(MayanAppConfig):
app_url = ''
has_rest_api = True
has_tests = True
name = 'common'
verbose_name = _('Common')
@@ -89,8 +89,6 @@ class CommonApp(MayanAppConfig):
def ready(self):
super(CommonApp, self).ready()
APIEndPoint(app=self, version_string='1')
app.conf.CELERYBEAT_SCHEDULE.update(
{
'task_delete_stale_uploads': {

View File

@@ -9,7 +9,6 @@ from common import (
MayanAppConfig, menu_facet, menu_object, menu_setup, menu_sidebar
)
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .classes import KeyStub
from .links import (
@@ -26,6 +25,7 @@ from .permissions import (
class DjangoGPGApp(MayanAppConfig):
app_url = 'gpg'
has_rest_api = True
has_tests = True
name = 'django_gpg'
verbose_name = _('Django GPG')
@@ -33,7 +33,6 @@ class DjangoGPGApp(MayanAppConfig):
def ready(self):
super(DjangoGPGApp, self).ready()
APIEndPoint(app=self, version_string='1')
Key = self.get_model('Key')
ModelPermission.register(

View File

@@ -8,7 +8,6 @@ from common import MayanAppConfig, menu_facet, menu_object, menu_sidebar
from documents.search import document_page_search, document_search
from events import ModelEventType
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .events import (
event_document_comment_create, event_document_comment_delete
@@ -25,6 +24,7 @@ from .permissions import (
class DocumentCommentsApp(MayanAppConfig):
app_namespace = 'comments'
app_url = 'comments'
has_rest_api = True
has_tests = True
name = 'document_comments'
verbose_name = _('Document comments')
@@ -32,8 +32,6 @@ class DocumentCommentsApp(MayanAppConfig):
def ready(self):
super(DocumentCommentsApp, self).ready()
APIEndPoint(app=self, version_string='1')
Document = apps.get_model(
app_label='documents', model_name='Document'
)

View File

@@ -18,7 +18,6 @@ from common.widgets import two_state_template
from documents.signals import post_document_created, post_initial_document_type
from mayan.celery import app
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .handlers import (
create_default_document_index, handler_delete_empty,
@@ -44,6 +43,7 @@ from .widgets import get_instance_link, index_instance_item_link, node_level
class DocumentIndexingApp(MayanAppConfig):
app_namespace = 'indexing'
app_url = 'indexing'
has_rest_api = True
has_tests = True
name = 'document_indexing'
verbose_name = _('Document indexing')
@@ -51,8 +51,6 @@ class DocumentIndexingApp(MayanAppConfig):
def ready(self):
super(DocumentIndexingApp, self).ready()
APIEndPoint(app=self, version_string='1')
Document = apps.get_model(
app_label='documents', model_name='Document'
)

View File

@@ -20,7 +20,6 @@ from documents.signals import post_version_upload
from documents.widgets import document_link
from mayan.celery import app
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .events import event_parsing_document_version_submit
from .handlers import handler_parse_document_version
@@ -56,6 +55,7 @@ def document_version_parsing_submit(self):
class DocumentParsingApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'document_parsing'
verbose_name = _('Document parsing')
@@ -63,8 +63,6 @@ class DocumentParsingApp(MayanAppConfig):
def ready(self):
super(DocumentParsingApp, self).ready()
APIEndPoint(app=self, version_string='1')
Document = apps.get_model(
app_label='documents', model_name='Document'
)

View File

@@ -18,7 +18,6 @@ from common.permissions_runtime import permission_error_log_view
from common.widgets import two_state_template
from mayan.celery import app
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .classes import DocumentStateHelper, WorkflowAction
from .handlers import (
@@ -52,6 +51,7 @@ from .widgets import widget_transition_events
class DocumentStatesApp(MayanAppConfig):
app_url = 'states'
has_rest_api = True
has_tests = True
name = 'document_states'
verbose_name = _('Document states')
@@ -59,8 +59,6 @@ class DocumentStatesApp(MayanAppConfig):
def ready(self):
super(DocumentStatesApp, self).ready()
APIEndPoint(app=self, version_string='1')
Action = apps.get_model(
app_label='actstream', model_name='Action'
)

View File

@@ -32,7 +32,6 @@ from events.permissions import permission_events_view
from mayan.celery import app
from mayan_statistics.classes import StatisticNamespace, CharJSLine
from navigation import SourceColumn
from rest_api.classes import APIEndPoint, APIResource
from rest_api.fields import DynamicSerializerField
from .dashboard_widgets import (
@@ -109,6 +108,7 @@ from .widgets import (
class DocumentsApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'documents'
verbose_name = _('Documents')
@@ -117,11 +117,6 @@ class DocumentsApp(MayanAppConfig):
super(DocumentsApp, self).ready()
from actstream import registry
APIEndPoint(app=self, version_string='1')
APIResource(label=_('Document types'), name='document_types')
APIResource(label=_('Documents'), name='documents')
APIResource(label=_('Trashed documents'), name='trashed_documents')
DeletedDocument = self.get_model('DeletedDocument')
Document = self.get_model('Document')
DocumentPage = self.get_model('DocumentPage')

View File

@@ -3,7 +3,6 @@ from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _
from common import MayanAppConfig, menu_facet, menu_sidebar
from rest_api.classes import APIEndPoint
from .links import link_search, link_search_advanced, link_search_again
@@ -11,6 +10,7 @@ from .links import link_search, link_search_advanced, link_search_again
class DynamicSearchApp(MayanAppConfig):
app_namespace = 'search'
app_url = 'search'
has_rest_api = True
has_tests = True
name = 'dynamic_search'
verbose_name = _('Dynamic search')
@@ -18,8 +18,6 @@ class DynamicSearchApp(MayanAppConfig):
def ready(self):
super(DynamicSearchApp, self).ready()
APIEndPoint(app=self, version_string='1')
menu_facet.bind_links(
links=(link_search, link_search_advanced),
sources=(

View File

@@ -10,7 +10,6 @@ from common import (
)
from common.widgets import two_state_template
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .links import (
link_events_list, link_event_types_subscriptions_list,
@@ -22,6 +21,7 @@ from .widgets import event_object_link, event_type_link, event_user_link
class EventsApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'events'
verbose_name = _('Events')
@@ -33,8 +33,6 @@ class EventsApp(MayanAppConfig):
StoredEventType = self.get_model(model_name='StoredEventType')
User = get_user_model()
APIEndPoint(app=self, version_string='1')
SourceColumn(
source=Action, label=_('Timestamp'), attribute='timestamp'
)

View File

@@ -12,7 +12,6 @@ from common import (
)
from common.widgets import two_state_template
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .links import (
link_smart_link_create, link_smart_link_condition_create,
@@ -29,6 +28,7 @@ from .permissions import (
class LinkingApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'linking'
verbose_name = _('Linking')
@@ -36,8 +36,6 @@ class LinkingApp(MayanAppConfig):
def ready(self):
super(LinkingApp, self).ready()
APIEndPoint(app=self, version_string='1')
Document = apps.get_model(
app_label='documents', model_name='Document'
)

View File

@@ -20,7 +20,6 @@ from documents.signals import post_document_type_change
from documents.permissions import permission_document_view
from mayan.celery import app
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .classes import DocumentMetadataHelper
from .handlers import (
@@ -51,6 +50,7 @@ logger = logging.getLogger(__name__)
class MetadataApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'metadata'
verbose_name = _('Metadata')
@@ -73,8 +73,6 @@ class MetadataApp(MayanAppConfig):
DocumentTypeMetadataType = self.get_model('DocumentTypeMetadataType')
MetadataType = self.get_model('MetadataType')
APIEndPoint(app=self, version_string='2')
Document.add_to_class(
'metadata_value_of', DocumentMetadataHelper.constructor
)

View File

@@ -7,7 +7,6 @@ from django.utils.translation import ugettext_lazy as _
from acls import ModelPermission
from common import MayanAppConfig, menu_object, menu_secondary, menu_setup
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .links import (
link_message_create, link_message_delete, link_message_edit,
@@ -22,6 +21,7 @@ logger = logging.getLogger(__name__)
class MOTDApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'motd'
verbose_name = _('Message of the day')
@@ -29,8 +29,6 @@ class MOTDApp(MayanAppConfig):
def ready(self):
super(MOTDApp, self).ready()
APIEndPoint(app=self, version_string='1')
Message = self.get_model('Message')
ModelPermission.register(
model=Message, permissions=(

View File

@@ -21,7 +21,6 @@ from documents.signals import post_version_upload
from documents.widgets import document_link
from mayan.celery import app
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .events import event_ocr_document_version_submit
from .handlers import (
@@ -61,6 +60,7 @@ def document_version_ocr_submit(self):
class OCRApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'ocr'
verbose_name = _('OCR')
@@ -68,8 +68,6 @@ class OCRApp(MayanAppConfig):
def ready(self):
super(OCRApp, self).ready()
APIEndPoint(app=self, version_string='1')
Document = apps.get_model(
app_label='documents', model_name='Document'
)

View File

@@ -8,7 +8,6 @@ from common import (
MayanAppConfig, menu_multi_item, menu_object, menu_secondary, menu_setup
)
from common.signals import perform_upgrade
from rest_api.classes import APIEndPoint
from .handlers import purge_permissions
from .links import (
@@ -23,6 +22,7 @@ from .search import * # NOQA
class PermissionsApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'permissions'
verbose_name = _('Permissions')
@@ -33,8 +33,6 @@ class PermissionsApp(MayanAppConfig):
Role = self.get_model('Role')
Group = apps.get_model(app_label='auth', model_name='Group')
APIEndPoint(app=self, version_string='1')
ModelPermission.register(
model=Role, permissions=(
permission_role_delete, permission_role_edit,

View File

@@ -1,16 +1,12 @@
from __future__ import unicode_literals
from rest_framework import generics
from .classes import APIResource
from .serializers import APIResourceSerializer
from rest_framework import generics, renderers
from rest_framework.authtoken.views import ObtainAuthToken
class APIResourceTypeListView(generics.ListAPIView):
class BrowseableObtainAuthToken(ObtainAuthToken):
"""
Returns a list of all the available API resources.
Obtain an API authentication token.
"""
serializer_class = APIResourceSerializer
def get_queryset(self):
return APIResource.all()
renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer)

View File

@@ -1,11 +1,12 @@
from __future__ import unicode_literals
from django.apps import apps
from django.conf import settings
from django.utils.module_loading import import_string
from django.utils.translation import ugettext_lazy as _
from common import MayanAppConfig, menu_tools
from .classes import APIEndPoint
from .links import link_api, link_api_documentation
from .licenses import * # NOQA
@@ -17,9 +18,12 @@ class RESTAPIApp(MayanAppConfig):
def ready(self):
super(RESTAPIApp, self).ready()
from .urls import api_urls
settings.STRONGHOLD_PUBLIC_URLS += (r'^/%s/.+$' % self.app_url,)
APIEndPoint(app=self, name='rest', version_string='1')
menu_tools.bind_links(links=(link_api, link_api_documentation))
for app in apps.get_app_configs():
if getattr(app, 'has_rest_api', False):
app_api_urls = import_string('{}.urls.api_urls'.format(app.label))
api_urls.extend(app_api_urls)

View File

@@ -1,83 +0,0 @@
from __future__ import unicode_literals
from django.conf import settings
from django.utils.encoding import force_text, python_2_unicode_compatible
from django.utils.module_loading import import_string
from .exceptions import APIResourcePatternError
@python_2_unicode_compatible
class APIResource(object):
_registry = {}
@classmethod
def all(cls):
return cls._registry.values()
@classmethod
def get(cls, name):
return cls._registry[name]
def __str__(self):
return force_text(self.name)
def __init__(self, name, label, description=None):
self.label = label
self.name = name
self.description = description
self.__class__._registry[self.name] = self
@python_2_unicode_compatible
class APIEndPoint(object):
_registry = {}
_patterns = []
@classmethod
def get_all(cls):
return cls._registry.values()
@classmethod
def get(cls, name):
return cls._registry[name]
def __str__(self):
return force_text(self.app.name)
def __init__(self, app, version_string, name=None):
self.app = app
self.endpoints = []
self.name = name
self.version_string = version_string
try:
api_urls = import_string(
'{0}.urls.api_urls'.format(app.name)
)
except Exception:
if settings.DEBUG:
raise
else:
# Ignore import time errors
pass
else:
self.register_urls(api_urls)
self.__class__._registry[app.name] = self
@property
def app_name(self):
return self.app.name
def register_urls(self, urlpatterns):
from .urls import urlpatterns as app_urls
for url in urlpatterns:
if url.regex.pattern not in self.__class__._patterns:
app_urls.append(url)
self.__class__._patterns.append(url.regex.pattern)
else:
raise APIResourcePatternError(
'App "{}" tried to register API URL pattern "{}", which '
'already exists'.format(self.app.label, url.regex.pattern)
)

View File

@@ -1,9 +0,0 @@
from __future__ import unicode_literals
from rest_framework import serializers
class APIResourceSerializer(serializers.Serializer):
description = serializers.CharField()
label = serializers.CharField()
name = serializers.CharField()

View File

@@ -1,21 +1,17 @@
from __future__ import unicode_literals
from django.conf.urls import url
from django.conf.urls import include, url
from .api_views import APIResourceTypeListView
from .views import APIBase, BrowseableObtainAuthToken
from .api_views import BrowseableObtainAuthToken
urlpatterns = []
api_urls = [
url(r'^$', APIBase.as_view(), name='api_root'),
url(
r'^resources/$', APIResourceTypeListView.as_view(),
name='resource-list'
),
url(
r'^auth/token/obtain/$', BrowseableObtainAuthToken.as_view(),
name='auth_token_obtain'
),
]
urlpatterns = [
url(r'^', include(api_urls)),
]

View File

@@ -1,21 +0,0 @@
from __future__ import unicode_literals
from rest_framework import renderers
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework_swagger.views import SwaggerResourcesView
class APIBase(SwaggerResourcesView):
"""
Main entry point of the API.
"""
renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer)
class BrowseableObtainAuthToken(ObtainAuthToken):
"""
Obtain an API authentication token.
"""
renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer)

View File

@@ -14,7 +14,6 @@ from documents.menus import menu_documents
from documents.signals import post_version_upload
from mayan.celery import app
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .classes import StagingFile
from .handlers import (
@@ -35,6 +34,7 @@ from .widgets import StagingFileThumbnailWidget
class SourcesApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'sources'
verbose_name = _('Sources')
@@ -51,8 +51,6 @@ class SourcesApp(MayanAppConfig):
WatchFolderSource = self.get_model('WatchFolderSource')
WebFormSource = self.get_model('WebFormSource')
APIEndPoint(app=self, version_string='1')
MissingItem(
label=_('Create a document source'),
description=_(

View File

@@ -12,7 +12,6 @@ from common import (
)
from documents.search import document_page_search, document_search
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .links import (
link_multiple_documents_attach_tag, link_multiple_documents_tag_remove,
@@ -30,6 +29,7 @@ from .widgets import widget_document_tags, widget_single_tag
class TagsApp(MayanAppConfig):
has_rest_api = True
has_tests = True
name = 'tags'
verbose_name = _('Tags')
@@ -49,8 +49,6 @@ class TagsApp(MayanAppConfig):
DocumentTag = self.get_model('DocumentTag')
Tag = self.get_model('Tag')
APIEndPoint(app=self, version_string='1')
Document.add_to_class(
'attached_tags',
lambda document: DocumentTag.objects.filter(documents=document)

View File

@@ -10,7 +10,6 @@ from common.apps import MayanAppConfig
from common.widgets import two_state_template
from metadata import MetadataLookup
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from rest_api.fields import DynamicSerializerField
from .links import (
@@ -44,6 +43,7 @@ def get_users():
class UserManagementApp(MayanAppConfig):
app_url = 'accounts'
has_rest_api = True
has_tests = True
name = 'user_management'
verbose_name = _('User management')
@@ -55,7 +55,6 @@ class UserManagementApp(MayanAppConfig):
Group = apps.get_model(app_label='auth', model_name='Group')
User = get_user_model()
APIEndPoint(app=self, version_string='1')
DynamicSerializerField.add_serializer(
klass=get_user_model(),
serializer_class='user_management.serializers.UserSerializer'