pyDMNrules-enhanced 1.5.0__tar.gz → 1.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/LICENSE_MCP +1 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/MANIFEST.in +1 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/MCP_PROJECT_SUMMARY.md +1 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/PKG-INFO +3 -13
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/SETUP_GUIDE.md +1 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules/DMNrules.py +151 -30
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules_enhanced.egg-info/PKG-INFO +3 -13
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pydmnrules_mcp/__init__.py +1 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/requirements_mcp.txt +1 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/setup.py +2 -2
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/LICENSE +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/README.md +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/README_MCP.md +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/claude_desktop_config.json +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules/__init__.py +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules_enhanced.egg-info/SOURCES.txt +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules_enhanced.egg-info/dependency_links.txt +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules_enhanced.egg-info/requires.txt +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules_enhanced.egg-info/top_level.txt +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pydmnrules_mcp/server.py +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyproject.toml +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/setup.cfg +0 -0
- {pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/tests/test_pyDMNrules.py +0 -0
@@ -1,7 +1,7 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.1
|
2
2
|
Name: pyDMNrules-enhanced
|
3
|
-
Version: 1.
|
4
|
-
Summary: Enhanced pyDMNrules with full
|
3
|
+
Version: 1.6.0
|
4
|
+
Summary: Enhanced pyDMNrules with full DRD support (informationRequirement/requiredInput auto-mapping)
|
5
5
|
Home-page: https://github.com/uengine/pyDMNrules
|
6
6
|
Author: Russell McDonell (Enhanced by uengine)
|
7
7
|
Author-email: russell.mcdonell@c-cost.com
|
@@ -16,16 +16,6 @@ Requires-Dist: datetime
|
|
16
16
|
Requires-Dist: pySFeel
|
17
17
|
Requires-Dist: openpyxl
|
18
18
|
Requires-Dist: pandas
|
19
|
-
Dynamic: author
|
20
|
-
Dynamic: author-email
|
21
|
-
Dynamic: classifier
|
22
|
-
Dynamic: description
|
23
|
-
Dynamic: description-content-type
|
24
|
-
Dynamic: home-page
|
25
|
-
Dynamic: license-file
|
26
|
-
Dynamic: requires-dist
|
27
|
-
Dynamic: requires-python
|
28
|
-
Dynamic: summary
|
29
19
|
|
30
20
|
# pyDMNrules
|
31
21
|
An implementation of DMN (Decision Model Notation) in Python, using the [pySFeel](https://pypi.org/project/pySFeel/), [openpyxl](https://pypi.org/project/openpyxl/) and [pandas](httpsL//pypi.org/project/pandas) modules.
|
@@ -44,6 +44,10 @@ class DMN():
|
|
44
44
|
self.isLoaded = False
|
45
45
|
self.testIsLoaded = False
|
46
46
|
self.decisionDependencies = {} # Decision ID -> list of required decision IDs
|
47
|
+
self.decisionIdToTables = {} # Decision ID -> list of table names
|
48
|
+
self.decisionTableToId = {} # Table name -> Decision ID
|
49
|
+
self.decisionRequiredInputs = {} # Decision ID -> list of required inputData IDs
|
50
|
+
self.inputDataIdToVariable = {} # InputData ID -> variable name
|
47
51
|
self.errors = []
|
48
52
|
self.DMNfunctions = [
|
49
53
|
'date(', 'time(', 'date and time(',
|
@@ -2341,6 +2345,10 @@ class DMN():
|
|
2341
2345
|
self.decisionName = ''
|
2342
2346
|
self.decisions = []
|
2343
2347
|
self.decisionDependencies = {} # Decision ID -> list of required decision IDs
|
2348
|
+
self.decisionIdToTables = {} # Decision ID -> list of table names
|
2349
|
+
self.decisionTableToId = {} # Table name -> Decision ID
|
2350
|
+
self.decisionRequiredInputs = {} # Decision ID -> list of required inputData IDs
|
2351
|
+
self.inputDataIdToVariable = {} # InputData ID -> variable name
|
2344
2352
|
self.decisionHeading = []
|
2345
2353
|
self.otherDecisions = []
|
2346
2354
|
self.decisionTables = {}
|
@@ -2936,18 +2944,29 @@ class DMN():
|
|
2936
2944
|
self.decisionHeading = [0, 'Decisions', 'Execute Decision Tables']
|
2937
2945
|
theseTables = list(self.decisionTables)
|
2938
2946
|
|
2939
|
-
#
|
2940
|
-
|
2941
|
-
|
2942
|
-
|
2943
|
-
for
|
2944
|
-
|
2945
|
-
|
2946
|
-
|
2947
|
-
if
|
2948
|
-
idToTable[dec_id] = table
|
2949
|
-
|
2950
|
-
|
2947
|
+
# Use the prebuilt mapping from decision IDs to table names
|
2948
|
+
# This mapping was created in useXML() from XMLdecisions
|
2949
|
+
if hasattr(self, 'decisionTableToId') and self.decisionTableToId:
|
2950
|
+
tableToId = self.decisionTableToId
|
2951
|
+
# Build reverse mapping: for each decision ID, get all its tables (first table only for simplicity)
|
2952
|
+
idToTable = {}
|
2953
|
+
if hasattr(self, 'decisionIdToTables') and self.decisionIdToTables:
|
2954
|
+
for dec_id, tables in self.decisionIdToTables.items():
|
2955
|
+
if tables:
|
2956
|
+
idToTable[dec_id] = tables[0] # Use first table as representative
|
2957
|
+
else:
|
2958
|
+
# Fallback to old matching logic if mappings not available
|
2959
|
+
idToTable = {}
|
2960
|
+
tableToId = {}
|
2961
|
+
if hasattr(self, 'decisionDependencies') and self.decisionDependencies:
|
2962
|
+
for dec_id in self.decisionDependencies:
|
2963
|
+
# Try to match decision ID with table name
|
2964
|
+
for table in self.decisionTables:
|
2965
|
+
# Match by ID or by name similarity
|
2966
|
+
if dec_id == table or dec_id.lower().replace('_', ' ') == table.lower():
|
2967
|
+
idToTable[dec_id] = table
|
2968
|
+
tableToId[table] = dec_id
|
2969
|
+
break
|
2951
2970
|
|
2952
2971
|
while len(theseTables) > 0:
|
2953
2972
|
for i in range(len(theseTables)): # Check every table looking for tables with no dependencies
|
@@ -3080,6 +3099,10 @@ class DMN():
|
|
3080
3099
|
self.decisionHeading = [0, 'Decisions', 'Execute Decision Tables'] # There are no input tests and there may be no annotations
|
3081
3100
|
self.decisions = []
|
3082
3101
|
self.decisionDependencies = {} # Decision ID -> list of required decision IDs
|
3102
|
+
self.decisionIdToTables = {} # Decision ID -> list of table names
|
3103
|
+
self.decisionTableToId = {} # Table name -> Decision ID
|
3104
|
+
self.decisionRequiredInputs = {} # Decision ID -> list of required inputData IDs
|
3105
|
+
self.inputDataIdToVariable = {} # InputData ID -> variable name
|
3083
3106
|
self.otherDecisions = []
|
3084
3107
|
self.decisionTables = {}
|
3085
3108
|
|
@@ -3093,7 +3116,9 @@ class DMN():
|
|
3093
3116
|
thisName = itemDefinition.get('name')
|
3094
3117
|
XMLitemDefinitions[thisName] = itemDefinition
|
3095
3118
|
XMLvariables = {}
|
3119
|
+
XMLinputDataMap = {} # Map inputData ID -> variable name
|
3096
3120
|
for inputData in root.iter(DMN + 'inputData'):
|
3121
|
+
inputDataId = inputData.get('id')
|
3097
3122
|
thisVariable = inputData.find('variable', namespaces=ns)
|
3098
3123
|
if thisVariable is None:
|
3099
3124
|
continue
|
@@ -3103,6 +3128,11 @@ class DMN():
|
|
3103
3128
|
status['errors'] = self.errors
|
3104
3129
|
return status
|
3105
3130
|
variable = thisVariable.get('name')
|
3131
|
+
|
3132
|
+
# Store mapping from inputData ID to variable name
|
3133
|
+
if inputDataId:
|
3134
|
+
XMLinputDataMap[inputDataId] = variable
|
3135
|
+
|
3106
3136
|
if 'typeRef' not in thisVariable.keys():
|
3107
3137
|
continue
|
3108
3138
|
typeRef = thisVariable.get('typeRef')
|
@@ -3190,17 +3220,23 @@ class DMN():
|
|
3190
3220
|
XMLvariables[variable] = typeRef
|
3191
3221
|
outputs = thisTable.findall('output', namespaces=ns)
|
3192
3222
|
for thisOutput in outputs:
|
3193
|
-
|
3223
|
+
# Prefer 'name' attribute over 'label' for output variable name (DMN standard)
|
3224
|
+
if 'name' in thisOutput.keys():
|
3225
|
+
variable = thisOutput.get('name')
|
3226
|
+
elif 'label' in thisOutput.keys():
|
3194
3227
|
variable = thisOutput.get('label')
|
3195
|
-
|
3196
|
-
|
3197
|
-
|
3198
|
-
|
3199
|
-
|
3200
|
-
|
3201
|
-
|
3202
|
-
|
3203
|
-
|
3228
|
+
else:
|
3229
|
+
continue
|
3230
|
+
|
3231
|
+
if (thisTable in XMLdecisionBindings) and (variable in XMLdecisionBindings[thisTable]):
|
3232
|
+
variable = XMLdecisionBindings[thisTable][variable]
|
3233
|
+
elif (decisionName in XMLdecisionVariables) and (len(XMLdecisionVariables[decisionName]) == 1) and (len(outputs) == 1):
|
3234
|
+
variable = XMLdecisionVariables[decisionName][0]
|
3235
|
+
if variable not in XMLvariables:
|
3236
|
+
outputExpression = thisOutput.find('inputExpression', namespaces=ns)
|
3237
|
+
if (outputExpression is not None) and ('typeRef' in outputExpression.keys()):
|
3238
|
+
typeRef = outputExpression.get('typeRef')
|
3239
|
+
XMLvariables[variable] = typeRef
|
3204
3240
|
|
3205
3241
|
for variable in XMLvariables:
|
3206
3242
|
typeRef = XMLvariables[variable]
|
@@ -3317,6 +3353,7 @@ class DMN():
|
|
3317
3353
|
XMLdecisions[-1]['tables'] = []
|
3318
3354
|
XMLdecisions[-1]['annotations'] = {}
|
3319
3355
|
XMLdecisions[-1]['required'] = []
|
3356
|
+
XMLdecisions[-1]['requiredInputs'] = [] # Track required inputData
|
3320
3357
|
XMLdecisions[-1]['done'] = False
|
3321
3358
|
for infoRequired in decision.findall('informationRequirement', namespaces=ns):
|
3322
3359
|
requiredDecision = infoRequired.find('requiredDecision', namespaces=ns)
|
@@ -3334,6 +3371,23 @@ class DMN():
|
|
3334
3371
|
status = {}
|
3335
3372
|
status['errors'] = self.errors
|
3336
3373
|
return status
|
3374
|
+
|
3375
|
+
# Also handle requiredInput (inputData -> decision)
|
3376
|
+
requiredInput = infoRequired.find('requiredInput', namespaces=ns)
|
3377
|
+
if requiredInput is not None:
|
3378
|
+
if 'href' not in requiredInput.keys():
|
3379
|
+
self.errors.append('Invalid XML')
|
3380
|
+
status = {}
|
3381
|
+
status['errors'] = self.errors
|
3382
|
+
return status
|
3383
|
+
inputRef = requiredInput.get('href')
|
3384
|
+
if inputRef[0] == '#': # Internal reference
|
3385
|
+
XMLdecisions[-1]['requiredInputs'].append(inputRef[1:]) # The 'id' of the required inputData
|
3386
|
+
else:
|
3387
|
+
self.errors.append('Invalid XML')
|
3388
|
+
status = {}
|
3389
|
+
status['errors'] = self.errors
|
3390
|
+
return status
|
3337
3391
|
|
3338
3392
|
# There can be multiple decisionTable for each decision
|
3339
3393
|
theseTables = list(decision.findall('decisionTable', namespaces=ns))
|
@@ -3703,8 +3757,11 @@ class DMN():
|
|
3703
3757
|
status = {}
|
3704
3758
|
status['errors'] = self.errors
|
3705
3759
|
return status
|
3706
|
-
variable
|
3707
|
-
|
3760
|
+
# Use inputExpression text as variable name (DMN standard)
|
3761
|
+
# The text is the FEEL expression that references the actual variable
|
3762
|
+
variable = text.text if text.text else ''
|
3763
|
+
# Only use label as fallback if text is empty
|
3764
|
+
if variable == '' and 'label' in inputVariable.keys():
|
3708
3765
|
variable = inputVariable.get('label')
|
3709
3766
|
if (table in XMLdecisionBindings) and (variable in XMLdecisionBindings[table]):
|
3710
3767
|
variable = XMLdecisionBindings[table][variable]
|
@@ -3845,16 +3902,17 @@ class DMN():
|
|
3845
3902
|
# Outputs should have a label (for linkage to inputs) and can have outputValues
|
3846
3903
|
outputs = []
|
3847
3904
|
for outputVariable in XMLdecisionTable.findall('output', namespaces=ns):
|
3848
|
-
|
3849
|
-
|
3850
|
-
variable = outputLabel
|
3851
|
-
else:
|
3852
|
-
variable = outputVariable.get('label')
|
3853
|
-
elif 'name' in outputVariable.keys():
|
3905
|
+
# Prefer 'name' attribute over 'label' for output variable name (DMN standard)
|
3906
|
+
if 'name' in outputVariable.keys():
|
3854
3907
|
if outputLabel != '':
|
3855
3908
|
variable = outputLabel + '.' + outputVariable.get('name')
|
3856
3909
|
else:
|
3857
3910
|
variable = outputVariable.get('name')
|
3911
|
+
elif 'label' in outputVariable.keys():
|
3912
|
+
if outputLabel != '':
|
3913
|
+
variable = outputLabel
|
3914
|
+
else:
|
3915
|
+
variable = outputVariable.get('label')
|
3858
3916
|
elif outputLabel != '':
|
3859
3917
|
variable = outputLabel
|
3860
3918
|
outputLabel = ''
|
@@ -4100,11 +4158,23 @@ class DMN():
|
|
4100
4158
|
|
4101
4159
|
# Save decision dependencies from XMLdecisions
|
4102
4160
|
self.decisionDependencies = {}
|
4161
|
+
self.decisionIdToTables = {} # Map decision ID to its table names
|
4162
|
+
self.decisionTableToId = {} # Map table name to its decision ID
|
4163
|
+
self.decisionRequiredInputs = {} # Map decision ID to required inputData IDs
|
4164
|
+
self.inputDataIdToVariable = XMLinputDataMap # Map inputData ID to variable name
|
4165
|
+
|
4103
4166
|
for xmlDec in XMLdecisions:
|
4104
4167
|
dec_id = xmlDec.get('id')
|
4105
4168
|
required_ids = xmlDec.get('required', [])
|
4169
|
+
required_inputs = xmlDec.get('requiredInputs', [])
|
4170
|
+
tables = xmlDec.get('tables', [])
|
4106
4171
|
if dec_id:
|
4107
4172
|
self.decisionDependencies[dec_id] = required_ids
|
4173
|
+
self.decisionRequiredInputs[dec_id] = required_inputs
|
4174
|
+
self.decisionIdToTables[dec_id] = tables
|
4175
|
+
# Create reverse mapping for each table
|
4176
|
+
for table in tables:
|
4177
|
+
self.decisionTableToId[table] = dec_id
|
4108
4178
|
|
4109
4179
|
# Now build a decision order
|
4110
4180
|
theseTables = self.buildDecision(theseInputs, theseOutputs)
|
@@ -5215,6 +5285,10 @@ class DMN():
|
|
5215
5285
|
self.errors = []
|
5216
5286
|
return (status, {})
|
5217
5287
|
self.initGlossary()
|
5288
|
+
|
5289
|
+
# Store original input data keys for later requiredInput mapping
|
5290
|
+
original_input_keys = set(data.keys())
|
5291
|
+
|
5218
5292
|
validData = True
|
5219
5293
|
for variable in data:
|
5220
5294
|
value = data[variable]
|
@@ -5271,6 +5345,53 @@ class DMN():
|
|
5271
5345
|
self.errors = []
|
5272
5346
|
return (status, {})
|
5273
5347
|
|
5348
|
+
# Handle requiredInput automatic mapping (inputData variable -> inputExpression text)
|
5349
|
+
# For each decision table, check if it has requiredInputs and map inputData values to inputExpression variables
|
5350
|
+
if hasattr(self, 'decisionTableToId') and hasattr(self, 'decisionRequiredInputs') and hasattr(self, 'inputDataIdToVariable'):
|
5351
|
+
for table_name in self.decisionTables:
|
5352
|
+
# Get the decision ID for this table
|
5353
|
+
if table_name in self.decisionTableToId:
|
5354
|
+
dec_id = self.decisionTableToId[table_name]
|
5355
|
+
# Get the required input IDs for this decision
|
5356
|
+
if dec_id in self.decisionRequiredInputs:
|
5357
|
+
required_input_ids = self.decisionRequiredInputs[dec_id]
|
5358
|
+
# Get the inputColumns for this table
|
5359
|
+
input_columns = self.decisionTables[table_name].get('inputColumns', [])
|
5360
|
+
|
5361
|
+
# Map each required inputData to corresponding inputExpression
|
5362
|
+
for i, input_data_id in enumerate(required_input_ids):
|
5363
|
+
if input_data_id in self.inputDataIdToVariable and i < len(input_columns):
|
5364
|
+
input_var_name = self.inputDataIdToVariable[input_data_id]
|
5365
|
+
input_expr_name = input_columns[i].get('name')
|
5366
|
+
|
5367
|
+
# If inputData variable exists in glossary and was provided
|
5368
|
+
if input_var_name in self.glossary and input_expr_name and input_var_name in original_input_keys:
|
5369
|
+
input_item = self.glossary[input_var_name]['item']
|
5370
|
+
# Get the value
|
5371
|
+
(failed, input_value) = self.sfeel('{}'.format(input_item))
|
5372
|
+
if not failed and input_value is not None:
|
5373
|
+
# Create a glossary entry for the inputExpression name if it doesn't exist
|
5374
|
+
if input_expr_name not in self.glossary:
|
5375
|
+
attribute = re.sub(self.badFEELchars, '', input_expr_name.replace(' ', '_'))
|
5376
|
+
expr_item = 'Data.' + attribute
|
5377
|
+
if expr_item not in self.glossaryItems:
|
5378
|
+
self.glossary[input_expr_name] = {}
|
5379
|
+
self.glossary[input_expr_name]['item'] = expr_item
|
5380
|
+
self.glossary[input_expr_name]['concept'] = 'Data'
|
5381
|
+
self.glossaryItems[expr_item] = input_expr_name
|
5382
|
+
thisLen = len(input_expr_name)
|
5383
|
+
if thisLen not in self.glossaryLen:
|
5384
|
+
self.glossaryLen[thisLen] = []
|
5385
|
+
self.glossaryLen[thisLen].append(input_expr_name)
|
5386
|
+
self.glossary[input_expr_name]['annotations'] = []
|
5387
|
+
|
5388
|
+
# Store the value under the inputExpression name
|
5389
|
+
if input_expr_name in self.glossary:
|
5390
|
+
expr_item = self.glossary[input_expr_name]['item']
|
5391
|
+
sFeelValue = self.value2sfeel(input_value)
|
5392
|
+
if sFeelValue is not None:
|
5393
|
+
(failed, retVal) = self.sfeel('{} <- {}'.format(expr_item, sFeelValue))
|
5394
|
+
|
5274
5395
|
# Initialize the status so we can detect circular references
|
5275
5396
|
for table in self.decisionTables:
|
5276
5397
|
self.decisionTables[table]['status'] = 'idle'
|
{pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules_enhanced.egg-info/PKG-INFO
RENAMED
@@ -1,7 +1,7 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.1
|
2
2
|
Name: pyDMNrules-enhanced
|
3
|
-
Version: 1.
|
4
|
-
Summary: Enhanced pyDMNrules with full
|
3
|
+
Version: 1.6.0
|
4
|
+
Summary: Enhanced pyDMNrules with full DRD support (informationRequirement/requiredInput auto-mapping)
|
5
5
|
Home-page: https://github.com/uengine/pyDMNrules
|
6
6
|
Author: Russell McDonell (Enhanced by uengine)
|
7
7
|
Author-email: russell.mcdonell@c-cost.com
|
@@ -16,16 +16,6 @@ Requires-Dist: datetime
|
|
16
16
|
Requires-Dist: pySFeel
|
17
17
|
Requires-Dist: openpyxl
|
18
18
|
Requires-Dist: pandas
|
19
|
-
Dynamic: author
|
20
|
-
Dynamic: author-email
|
21
|
-
Dynamic: classifier
|
22
|
-
Dynamic: description
|
23
|
-
Dynamic: description-content-type
|
24
|
-
Dynamic: home-page
|
25
|
-
Dynamic: license-file
|
26
|
-
Dynamic: requires-dist
|
27
|
-
Dynamic: requires-python
|
28
|
-
Dynamic: summary
|
29
19
|
|
30
20
|
# pyDMNrules
|
31
21
|
An implementation of DMN (Decision Model Notation) in Python, using the [pySFeel](https://pypi.org/project/pySFeel/), [openpyxl](https://pypi.org/project/openpyxl/) and [pandas](httpsL//pypi.org/project/pandas) modules.
|
@@ -5,10 +5,10 @@ with open('README.md', 'r') as fh:
|
|
5
5
|
|
6
6
|
setuptools.setup(
|
7
7
|
name='pyDMNrules-enhanced',
|
8
|
-
version='1.
|
8
|
+
version='1.6.0',
|
9
9
|
author='Russell McDonell (Enhanced by uengine)',
|
10
10
|
author_email='russell.mcdonell@c-cost.com',
|
11
|
-
description='Enhanced pyDMNrules with full
|
11
|
+
description='Enhanced pyDMNrules with full DRD support (informationRequirement/requiredInput auto-mapping)',
|
12
12
|
long_description=long_description,
|
13
13
|
long_description_content_type='text/markdown',
|
14
14
|
url='https://github.com/uengine/pyDMNrules',
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules_enhanced.egg-info/SOURCES.txt
RENAMED
File without changes
|
File without changes
|
{pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules_enhanced.egg-info/requires.txt
RENAMED
File without changes
|
{pydmnrules_enhanced-1.5.0 → pydmnrules_enhanced-1.6.0}/pyDMNrules_enhanced.egg-info/top_level.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|