After a year of procrastination, I've finally written a script that makes the CIM module sane:
https://github.com/hwelch-fle/cimple
The goal here is to generate a new cim module from the existing one with the added benefit of proper typing of dependent attributes and string literal completion. The overall structure and usability of the CIM is also improved by utilizing dataclasses and removing the original inheritance hierarchy in favor of direct attribute definition.
Example:
# Original CIM definition
class CIMChart():
"""
Provides access to members that control chart properties.
"""
def __init__(self, *args, **Kwargs):
self.name = str()
self.series = []
self.generalProperties = 'CIMChartGeneralProperties'
self.legend = 'CIMChartLegend'
self.axes = []
self.mapSelectionHandling = ChartMapSelectionHandling.Highlight
self.metaData = str()
self.multiSeriesChartProperties = 'CIMMultiSeriesChartProperties'
self.enableServerSideProcessing = False
self.chartType = ChartType.Basic
# cimple CIM definition
@dataclass
class CIMChart:
"""https://github.com/Esri/cim-spec/blob/main/docs/v3/CIMCharts.md#cimchart-1
Provides access to members that control chart properties.
"""
name: str = ''
series: list[Any] = dc_field(default_factory=list[Any])
generalProperties: CIMChartGeneralProperties = dc_field(default_factory=lambda: CIMChartGeneralProperties())
legend: CIMChartLegend = dc_field(default_factory=lambda: CIMChartLegend())
axes: list[Any] = dc_field(default_factory=list[Any])
mapSelectionHandling: ChartMapSelectionHandling = 'Highlight'
metaData: str = ''
multiSeriesChartProperties: CIMMultiSeriesChartProperties = dc_field(default_factory=lambda: CIMMultiSeriesChartProperties())
enableServerSideProcessing: bool = False
chartType: ChartType = 'Basic'
The dc_field factories replace the GetPythonClass call and allow for mutable defaults. There are still some lists and dictionaries that use the Any type since I could'nt infer their type from the original module.
This is a great idea. Thanks for sharing.
Replacing the current CIM’s string-heavy, inheritance-based model with dataclasses and proper typing makes a huge difference in usability, IDE autocomplete, and code safety. The default_factory approach alone removes a lot of hidden foot-guns.
Even with some remaining Any types, this already makes CIM far more usable for real development. With a bit of versioning clarity and round-trip validation, this could easily become the preferred way to work with CIM in Pro.
@VenkataKondepati Please test it out of you have the chance. I threw this script together in a day so I'm sure there will be some issues and I'd love to have your input.
My goal is to basically create a better cim that's both backwards compatible and also built on the old so they can just add this to their CI pipeline for releases. Maybe just hiding this new cim in a cim._types submodule?
This is also a decent test of the cim since it initializes all classes to infer their attributes and types. I found one class definition that was invalid which would absolutely **bleep** me off if I needed to use it (see my post in Python Questions)
Hi @HaydenWelch,
I am waiting for ArcGIS Pro license since my new company is still trying to become an ESRI partner.
I will test it in next couple of weeks.
Wish you a Happy New Year!!!
Regards,
Venkat
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.