Skip to content

Commit

Permalink
[#4396] Added basic plugin and necessary views and endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
vaszig committed Aug 23, 2024
1 parent 2752e19 commit bd0ed40
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/configuration/prefill/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ Prefill plugins
kvk
stuf_bg
suwinet
objects_api
3 changes: 3 additions & 0 deletions docs/developers/plugins/prefill_plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ You can find an example implementation in :mod:`openforms.prefill.contrib.demo`.
Implementation
--------------

Plugins must be added to the INSTALLED_APPS :mod:`openforms.conf.base`. See the demo app as an example
("openforms.prefill.contrib.demo.apps.DemoApp")

Plugins must implement the interface from :class:`openforms.prefill.base.BasePlugin`.
It's safe to use this as a base class.

Expand Down
1 change: 1 addition & 0 deletions src/openforms/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@
"openforms.prefill.contrib.stufbg.apps.StufBgApp",
"openforms.prefill.contrib.haalcentraal_brp.apps.HaalCentraalBRPApp",
"openforms.prefill.contrib.suwinet.apps.SuwinetApp",
"openforms.prefill.contrib.objects_api.apps.ObjectsApiApp",
"openforms.authentication",
"openforms.authentication.contrib.demo.apps.DemoApp",
"openforms.authentication.contrib.outage.apps.DemoOutageApp",
Expand Down
11 changes: 11 additions & 0 deletions src/openforms/prefill/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,14 @@ class PrefillAttributeSerializer(serializers.Serializer):
label=_("Label"),
help_text=_("The human-readable name for an attribute."),
)


class PrefillObjectsAPIAttributeSerializer(serializers.Serializer):
id = serializers.CharField(
label=_("ID"),
help_text=_("The unique attribute identifier"),
)
label = serializers.CharField(
label=_("Label"),
help_text=_("The human-readable name for an attribute."),
)
23 changes: 22 additions & 1 deletion src/openforms/prefill/api/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
from django.urls import path

from .views import PluginAttributesListView, PluginListView
from .views import (
PluginAttributesListView,
PluginListView,
PluginObjectsAPIAttributesListView,
PluginObjectsAPIObjecttypeListView,
PluginObjectsAPIObjecttypeVersionListView,
)

urlpatterns = [
path(
"plugins/objects-api/objecttypes",
PluginObjectsAPIObjecttypeListView.as_view(),
name="prefill-objects-api-objecttype-list",
),
path(
"plugins/objects-api/objecttypes/<uuid:objects_api_objecttype_uuid>/versions",
PluginObjectsAPIObjecttypeVersionListView.as_view(),
name="prefill-objects-api-objecttype-version-list",
),
path(
"plugins/objects-api/objecttypes/<uuid:objects_api_objecttype_uuid>/versions/<int:objects_api_objecttype_version>/attributes",
PluginObjectsAPIAttributesListView.as_view(),
name="prefill-objects-api-objecttype-attribute-list",
),
path("plugins", PluginListView.as_view(), name="prefill-plugin-list"),
path(
"plugins/<slug:plugin>/attributes",
Expand Down
94 changes: 93 additions & 1 deletion src/openforms/prefill/api/views.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
from typing import Any

from django.utils.translation import gettext_lazy as _

from drf_spectacular.utils import extend_schema, extend_schema_view
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema, extend_schema_view
from rest_framework import authentication, permissions
from rest_framework.exceptions import NotFound
from rest_framework.views import APIView

from openforms.api.views import ListMixin
from openforms.registrations.contrib.objects_api.api.serializers import (
ObjectsAPIGroupInputSerializer,
)
from openforms.registrations.contrib.objects_api.client import get_objecttypes_client

from ..registry import register
from .serializers import (
ChoiceWrapper,
PrefillAttributeSerializer,
PrefillObjectsAPIAttributeSerializer,
PrefillPluginQueryParameterSerializer,
PrefillPluginSerializer,
)
from openforms.registrations.contrib.objects_api.api.views import (
ObjecttypesListView,
ObjecttypeVersionsListView,
)
from openforms.registrations.contrib.objects_api.api.serializers import (
ObjecttypeVersionSerializer,
)

OBJECTS_API_GROUP_QUERY_PARAMETER = OpenApiParameter(
name="objects_api_group",
type=OpenApiTypes.STR,
location=OpenApiParameter.QUERY,
description=_("Which Objects API group to use."),
)


@extend_schema_view(
Expand Down Expand Up @@ -67,3 +89,73 @@ def get_objects(self):
choices = plugin.get_available_attributes()

return [ChoiceWrapper(choice) for choice in choices]


@extend_schema_view(
get=extend_schema(summary=_("List available objecttypes for Objects API")),
parameters=[OBJECTS_API_GROUP_QUERY_PARAMETER],
)
class PluginObjectsAPIObjecttypeListView(ObjecttypesListView):
"""
List the available prefill objecttypes for Objects API plugin.
"""

pass


@extend_schema_view(
get=extend_schema(summary=_("List available objecttype versions for Objects API")),
parameters=[OBJECTS_API_GROUP_QUERY_PARAMETER],
)
class PluginObjectsAPIObjecttypeVersionListView(ObjecttypeVersionsListView):
"""
List the available prefill objecttype versions for Objects API plugin.
"""

def get_objects(self):
input_serializer = ObjectsAPIGroupInputSerializer(
data=self.request.query_params
)
input_serializer.is_valid(raise_exception=True)

config_group = input_serializer.validated_data["objects_api_group"]
objecttype_uuid = self.kwargs["objects_api_objecttype_uuid"]

with get_objecttypes_client(config_group) as client:
return client.list_objecttype_versions(objecttype_uuid)


@extend_schema_view(
get=extend_schema(summary=_("List available attributes for Objects API")),
parameters=[OBJECTS_API_GROUP_QUERY_PARAMETER],
)
class PluginObjectsAPIAttributesListView(ListMixin, APIView):
"""
List the available attributes for Objects API plugin.
"""

authentication_classes = (authentication.SessionAuthentication,)
permission_classes = (permissions.IsAdminUser,)
serializer_class = PrefillObjectsAPIAttributeSerializer

def get_objects(self):
plugin = register["objects_api"]
input_serializer = ObjectsAPIGroupInputSerializer(
data=self.request.query_params
)
input_serializer.is_valid(raise_exception=True)

config_group = input_serializer.validated_data["objects_api_group"]
choices = plugin.get_available_attributes(
reference={
"objects_api_group": config_group,
"objects_api_objecttype_uuid": self.kwargs[
"objects_api_objecttype_uuid"
],
"objects_api_objecttype_version": self.kwargs[
"objects_api_objecttype_version"
],
}
)

return choices
7 changes: 6 additions & 1 deletion src/openforms/prefill/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ class BasePlugin(AbstractBasePlugin):
for_components: Container[str] = AllComponentTypes()

@staticmethod
def get_available_attributes() -> Iterable[tuple[str, str]]:
def get_available_attributes(
reference: dict[str, str] | None = None,
) -> Iterable[tuple[str, str]]:
"""
Return a choice list of available attributes this plugin offers.
:param reference: a dict based on which we retrieve the available attributes.
Can be used when we have dynamic lists of attributes.
"""
raise NotImplementedError(
"You must implement the 'get_available_attributes' method."
Expand Down
3 changes: 3 additions & 0 deletions src/openforms/prefill/contrib/objects_api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Objects API prefill plugin.
"""
12 changes: 12 additions & 0 deletions src/openforms/prefill/contrib/objects_api/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _


class ObjectsApiApp(AppConfig):
name = "openforms.prefill.contrib.objects_api"
label = "objects_api"
verbose_name = _("Objects API prefill plugin")

def ready(self):
# register the plugin
from . import plugin # noqa
44 changes: 44 additions & 0 deletions src/openforms/prefill/contrib/objects_api/plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import logging
from typing import Any, Iterable

from django.utils.translation import gettext_lazy as _

from openforms.authentication.service import AuthAttribute

from openforms.submissions.models import Submission
from openforms.typing import JSONEncodable

from ...base import BasePlugin
from ...constants import IdentifierRoles
from ...registry import register

logger = logging.getLogger(__name__)

PLUGIN_IDENTIFIER = "objects_api"


@register(PLUGIN_IDENTIFIER)
class ObjectsAPIPrefill(BasePlugin):
verbose_name = _("Objects API")
requires_auth = AuthAttribute.bsn

@staticmethod
def get_available_attributes(
reference: dict[str, Any] | None = None,
) -> Iterable[tuple[str, str]]:
pass

@classmethod
def get_prefill_values(
cls,
submission: Submission,
attributes: list[str],
identifier_role: IdentifierRoles = IdentifierRoles.main,
) -> dict[str, JSONEncodable]:
pass

@classmethod
def get_co_sign_values(
cls, submission: Submission, identifier: str
) -> tuple[dict[str, Any], str]:
pass

0 comments on commit bd0ed40

Please sign in to comment.