Skip to content

Commit

Permalink
✨ [#5012] Add metadata to JSON dump configuration options
Browse files Browse the repository at this point in the history
Also add support for an extra static variables registry in generate_json_schema
  • Loading branch information
viktorvanwijk committed Jan 30, 2025
1 parent 52b6e3c commit 8c83704
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 12 deletions.
19 changes: 16 additions & 3 deletions src/openforms/forms/json_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,46 @@
from openforms.variables.service import get_static_variables

from .models import Form, FormVariable
from ..plugins.registry import BaseRegistry
from ..variables.base import BaseStaticVariable


def _iter_form_variables(form: Form) -> Iterator[FormVariable]:
def _iter_form_variables(
form: Form, variables_registry: BaseRegistry[BaseStaticVariable] | None = None
) -> Iterator[FormVariable]:
"""Iterate over static variables and all form variables.
:param form: Form
:param variables_registry: Optional registry of static variables.
"""
# Static variables are always available
yield from get_static_variables()
# If the optional variables registry is passed
if variables_registry is not None:
yield from get_static_variables(variables_registry=variables_registry)
# Handle from variables holding dynamic data (component and user defined)
yield from form.formvariable_set.all()


def generate_json_schema(form: Form, limit_to_variables: Sequence[str]) -> JSONObject:
def generate_json_schema(
form: Form,
limit_to_variables: Sequence[str],
variables_registry: BaseRegistry[BaseStaticVariable] | None = None,
) -> JSONObject:
"""Generate a JSON schema from a form, for the specified variables.
Note: this schema is an informative description of the variables and should not be
used as validation.
:param form: The form to generate JSON schema for.
:param limit_to_variables: Variables that will be included in the schema.
:param variables_registry: Optional registry of static variables.
:returns: A JSON schema representing the form variables.
"""
requested_variables_schema = {
key: variable.as_json_schema()
for variable in _iter_form_variables(form)
for variable in _iter_form_variables(form, variables_registry)
if (key := variable.key) in limit_to_variables
}

Expand Down
25 changes: 25 additions & 0 deletions src/openforms/registrations/contrib/json_dump/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,29 @@ class JSONDumpOptionsSerializer(JsonSchemaSerializerMixin, serializers.Serialize
required=True,
min_length=1,
)
required_metadata_variables = serializers.ListField(
child=FormioVariableKeyField(),
default=[
"public_reference",
"form_name",
"form_version",
"registration_timestamp",
"auth_type",
],
label=_("Required metadata variable key list"),
help_text=_(
"A list of required variables to use in the metadata. These include "
"the registration variables of the JSON dump plugin"
),
required=False,
)
additional_metadata_variables = serializers.ListField(
child=FormioVariableKeyField(),
label=_("Additional metadata variable key list"),
help_text=_("A list of additional variables to use in the metadata"),
required=False,
default=[],
)


class JSONDumpOptions(TypedDict):
Expand All @@ -60,3 +83,5 @@ class JSONDumpOptions(TypedDict):
service: Service
path: str
variables: list[str]
required_metadata_variables: list[str]
additional_metadata_variables: list[str]
53 changes: 44 additions & 9 deletions src/openforms/registrations/contrib/json_dump/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@
SelectComponent,
)
from openforms.forms.json_schema import generate_json_schema
from openforms.forms.models import FormVariable
from openforms.submissions.models import Submission, SubmissionFileAttachment
from openforms.submissions.service import DataContainer
from openforms.typing import JSONObject
from openforms.utils.json_schema import to_multiple
from openforms.variables.constants import FormVariableSources
from openforms.variables.service import get_static_variables

from ...base import BasePlugin # openforms.registrations.base
from ...registry import register # openforms.registrations.registry
from .config import JSONDumpOptions, JSONDumpOptionsSerializer
from .registration_variables import register as variables_registry


@register("json_dump")
Expand All @@ -38,27 +41,56 @@ def register_submission(
) -> dict:
state = submission.load_submission_value_variables_state()

# Generate values
# TODO: keys with a period (e.g. `foo.bar`) will currently not be added to the
# submission data. This will be fixed with issue 5041
# Get static values
static_values = state.get_static_data()
# Update static values with registration variables
static_values.update(state.get_static_data(other_registry=variables_registry))

all_values: JSONObject = {
**state.get_static_data(),
**static_values,
**state.get_data(), # dynamic values from user input
}

# Values
values = {
key: value
for key, value in all_values.items()
if key in options["variables"]
}

# Generate schema
schema = generate_json_schema(submission.form, options["variables"])

# Post-processing
post_process(values, schema, submission)
values_schema = generate_json_schema(submission.form, options["variables"])
post_process(values, values_schema, submission)

# Metadata
# Note: as the metadata contains static variables (TODO-5012: do we need a validator for this?)
# no post-processing is required.
metadata_variables = [
*options["required_metadata_variables"],
*options["additional_metadata_variables"],
]
metadata = {
key: value for key, value in all_values.items() if key in metadata_variables
}
# TODO-5012: maybe it is better to just generate the schemas here by iterating
# over get_static_variables(), as we don't need the dynamic values anyway.
# Though, all the schema generation will stay together now, which is also nice
metadata_schema = generate_json_schema(
submission.form,
metadata_variables,
variables_registry=variables_registry,
)

# Send to the service
data = json.dumps({"values": values, "schema": schema}, cls=DjangoJSONEncoder)
data = json.dumps(
{
"values": values,
"values_schema": values_schema,
"metadata": metadata,
"metadata_schema": metadata_schema,
},
cls=DjangoJSONEncoder,
)
service = options["service"]
with build_client(service) as client:
if ".." in (path := options["path"]):
Expand All @@ -73,6 +105,9 @@ def check_config(self) -> None:
# Config checks are not really relevant for this plugin right now
pass

def get_variables(self) -> list[FormVariable]:
return get_static_variables(variables_registry=variables_registry)


def post_process(
values: JSONObject, schema: JSONObject, submission: Submission
Expand Down

0 comments on commit 8c83704

Please sign in to comment.