Skip to content

Feat: Introduce dynamic property mixin and add dynamic props to native view#1366

Open
onefloid wants to merge 2 commits intomasterfrom
feat/dynamic-props-native-view
Open

Feat: Introduce dynamic property mixin and add dynamic props to native view#1366
onefloid wants to merge 2 commits intomasterfrom
feat/dynamic-props-native-view

Conversation

@onefloid
Copy link
Collaborator

What changed

  • Introduce dynamic property mixin
  • Add dynamic property support to native view

@onefloid onefloid added the release:patch Triggers patch version bump (e.g.: 1.4.9 → 1.4.10) label Mar 14, 2026
@MariusWirtz MariusWirtz requested a review from Copilot March 16, 2026 10:24
dynamic_props = self._filter_dynamic_properties(self._dynamic_properties)
if dynamic_props:
bottom_json += "," + json.dumps(dynamic_props, ensure_ascii=False)[1:-1]
bottom_json += "}"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a bit archaic, how we're constructing the JSON here via string concatenation.
This PR is a good opportunity to clean up this part of the code base.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a shared mechanism to preserve “dynamic” (extra/unknown) REST properties on view objects and extends that support to NativeView, with accompanying unit/integration tests to validate round-tripping and REST retrieval.

Changes:

  • Added DynamicPropertiesMixin to centralize storage and filtering of extra REST properties via .dynamic_properties.
  • Updated MDXView and NativeView to use the mixin and include dynamic properties in (de)serialization.
  • Added tests covering dynamic properties defaults, constructor behavior, serialization, and REST create/get for native views.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Tests/ViewService_test.py Adds integration test that creates/retrieves/deletes a native view with dynamic properties.
Tests/NativeView_test.py Adds unit tests for NativeView.dynamic_properties defaults, serialization, and from-dict behavior.
TM1py/Services/ViewService.py Adjusts view retrieval to use shared dynamic property filtering for MDX/native views.
TM1py/Objects/NativeView.py Adds dynamic property support and serializes filtered dynamic properties into the request body.
TM1py/Objects/MDXView.py Refactors dynamic property handling to the shared mixin and shared filtering method.
TM1py/Objects/DynamicPropertiesMixin.py New mixin providing .dynamic_properties and _filter_dynamic_properties().

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +411 to +465
dynamic_properties = {
"Meta": {
"ExpandAboves": {
f"[{self.dimension_names[0]}].[{self.dimension_names[0]}]": False,
f"[{self.dimension_names[1]}].[{self.dimension_names[1]}]": False,
f"[{self.dimension_names[2]}].[{self.dimension_names[2]}]": False,
}
}
}
native_view = NativeView(
cube_name=self.cube_name,
view_name=self.native_view_with_dynamic_properties_name,
suppress_empty_columns=True,
suppress_empty_rows=True,
dynamic_properties=dynamic_properties,
)
subset = AnonymousSubset(
dimension_name=self.dimension_names[0],
hierarchy_name=self.dimension_names[0],
elements=["Element 1", "Element 2", "Element 3"],
)
native_view.add_column(dimension_name=self.dimension_names[0], subset=subset)
subset = AnonymousSubset(
dimension_name=self.dimension_names[1],
hierarchy_name=self.dimension_names[1],
elements=["Element 1"],
)
native_view.add_title(dimension_name=self.dimension_names[1], subset=subset, selection="Element 1")
subset = AnonymousSubset(
dimension_name=self.dimension_names[2],
hierarchy_name=self.dimension_names[2],
elements=["Element 1", "Element 2"],
)
native_view.add_row(dimension_name=self.dimension_names[2], subset=subset)
self.tm1.views.create(view=native_view, private=private)
self.assertTrue(
self.tm1.views.exists(
cube_name=self.cube_name,
view_name=self.native_view_with_dynamic_properties_name,
private=private,
)
)
retrieved = self.tm1.views.get_native_view(
cube_name=self.cube_name,
view_name=self.native_view_with_dynamic_properties_name,
private=private,
)
self.assertEqual(dynamic_properties, retrieved.dynamic_properties)
self.assertIsInstance(retrieved, NativeView)
self.assertEqual(self.native_view_with_dynamic_properties_name, retrieved.name)
self.tm1.views.delete(
cube_name=self.cube_name,
view_name=self.native_view_with_dynamic_properties_name,
private=private,
)
Comment on lines +74 to +76
dynamic_properties = NativeView._filter_dynamic_properties(view_as_dict)
return self.get_native_view(
cube_name=cube_name, view_name=view_name, private=private, dynamic_properties=dynamic_properties
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:patch Triggers patch version bump (e.g.: 1.4.9 → 1.4.10)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants