Skip to content

Commit 76edf2f

Browse files
committed
Fixed an issue where the SDK was parsing bodies badly
1 parent 0c2d3e9 commit 76edf2f

2 files changed

Lines changed: 103 additions & 10 deletions

File tree

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name='shuffle_sdk',
5-
version='0.0.33',
5+
version='0.0.34',
66
description='The SDK used for Shuffle',
77
py_modules=["shuffle_sdk"],
88
license='MIT',

shuffle_sdk/shuffle_sdk.py

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,6 @@ def __init__(self, redis=None, logger=None, console_logger=None):#, docker_clien
411411
if len(self.base_url) == 0:
412412
self.base_url = self.url
413413

414-
415414
self.local_storage = []
416415

417416
def init_singul(self):
@@ -2030,7 +2029,7 @@ def execute_action(self, action):
20302029
shouldExit = False
20312030

20322031
if shouldExit:
2033-
self.logger.info("[WARNING] ACTION env not defined. Checking if ran manually")
2032+
self.logger.info("[WARNING] ACTION env not defined (1). Checking if ran manually")
20342033
self.action_result["result"] = "Error in setup ENV: ACTION not defined. Use 'python3 shuffle_sdk.py standalone --action=action' to run standalone"
20352034
self.send_result(self.action_result, headers, stream_path)
20362035
return
@@ -2111,13 +2110,13 @@ def execute_action(self, action):
21112110
action = self.action
21122111

21132112
if len(self.authorization) == 0:
2114-
self.logger.info("[WARING] AUTHORIZATION env not defined")
2113+
self.logger.info("[WARING] AUTHORIZATION env not defined (2)")
21152114
self.action_result["result"] = "Error in setup ENV: AUTHORIZATION not defined"
21162115
self.send_result(self.action_result, headers, stream_path)
21172116
return
21182117

21192118
if len(self.current_execution_id) == 0:
2120-
self.logger.info("[WARNING] EXECUTIONID env not defined")
2119+
self.logger.info("[WARNING] EXECUTIONID env not defined (3)")
21212120
self.action_result["result"] = "Error in setup ENV: EXECUTIONID not defined"
21222121
self.send_result(self.action_result, headers, stream_path)
21232122
return
@@ -3171,9 +3170,9 @@ def parse_liquid(template, self):
31713170

31723171
return template
31733172

3174-
# Suboptimal cleanup script for BOdy parsing of OpenAPI
3173+
# Suboptimal cleanup script for Body parsing of OpenAPI
31753174
# Should have a regex which looks for the value, then goes out and cleans up the key
3176-
def recurse_cleanup_script(data):
3175+
def recurse_cleanup_script_old(data):
31773176
deletekeys = []
31783177
newvalue = data
31793178
try:
@@ -3201,7 +3200,7 @@ def recurse_cleanup_script(data):
32013200
continue
32023201

32033202
if isinstance(value, dict):
3204-
newvalue[key] = recurse_cleanup_script(value)
3203+
newvalue[key] = recurse_cleanup_script_old(value)
32053204

32063205
except json.decoder.JSONDecodeError as e:
32073206
# Since here the data isn't at all JSON compatible..?
@@ -3246,6 +3245,99 @@ def recurse_cleanup_script(data):
32463245

32473246
return data
32483247

3248+
3249+
def recurse_cleanup_script(data):
3250+
deletekeys = []
3251+
3252+
# TRACKING: specific fix to ensure Output Type == Input Type
3253+
input_was_string = False
3254+
3255+
# 1. SETUP: Ensure we are working with a Dict/List object
3256+
try:
3257+
if isinstance(data, str):
3258+
input_was_string = True
3259+
newvalue = json.loads(data)
3260+
else:
3261+
newvalue = data
3262+
except Exception:
3263+
# If we can't parse it, return as is (original behavior)
3264+
return data
3265+
3266+
# 2. MAIN LOOP: Iterate over the dictionary
3267+
# We wrap in list() to avoid runtime errors if we modify keys during iteration
3268+
if isinstance(newvalue, dict):
3269+
for key, value in list(newvalue.items()):
3270+
3271+
# --- CHECK: Empty Strings ---
3272+
if isinstance(value, str) and len(value) == 0:
3273+
deletekeys.append(key)
3274+
continue
3275+
3276+
# --- CHECK: Lists (FIXED) ---
3277+
# ORIGINAL BUG: It used to json.dumps(list), turning it into a string.
3278+
# FIX: We iterate the list items instead.
3279+
if isinstance(value, list):
3280+
cleaned_list = []
3281+
for item in value:
3282+
# If the item is a dict, recurse into it
3283+
if isinstance(item, dict):
3284+
cleaned_item = recurse_cleanup_script(item)
3285+
# Only add it back if it's not empty (optional, matches your aggressive cleanup style)
3286+
if cleaned_item:
3287+
cleaned_list.append(cleaned_item)
3288+
# If it's a string, run the specific bad-var checks
3289+
elif isinstance(item, str):
3290+
# Logic from your original script:
3291+
if "${" in item and "}" in item:
3292+
continue # Skip this bad item (delete it), but keep the list
3293+
if len(item) == 0:
3294+
continue
3295+
cleaned_list.append(item)
3296+
else:
3297+
cleaned_list.append(item)
3298+
3299+
newvalue[key] = cleaned_list
3300+
continue
3301+
3302+
# --- CHECK: Strings with Variables ---
3303+
# (Matches your original logic, but ensures we only check actual strings)
3304+
if isinstance(value, str):
3305+
if value == "${%s}" % key:
3306+
deletekeys.append(key)
3307+
continue
3308+
elif "${" in value and "}" in value:
3309+
deletekeys.append(key)
3310+
continue
3311+
3312+
# --- CHECK: Recursion (FIXED) ---
3313+
if isinstance(value, dict):
3314+
# FIX: We do NOT json.dumps here. We keep it as an object.
3315+
child_result = recurse_cleanup_script(value)
3316+
3317+
# If child became empty after cleanup, we might want to delete the key
3318+
if not child_result:
3319+
deletekeys.append(key)
3320+
else:
3321+
newvalue[key] = child_result
3322+
3323+
# 3. DELETE KEYS
3324+
for deletekey in deletekeys:
3325+
try:
3326+
del newvalue[deletekey]
3327+
except:
3328+
pass
3329+
3330+
# 4. FINAL RETURN (FIXED)
3331+
# Only convert back to JSON string if the INPUT was a string.
3332+
if input_was_string:
3333+
try:
3334+
return json.dumps(newvalue)
3335+
except:
3336+
return newvalue
3337+
else:
3338+
return newvalue
3339+
3340+
32493341
# Parses parameters sent to it and returns whether it did it successfully with the values found
32503342
def parse_params(action, fullexecution, parameter, self):
32513343
# Skip if it starts with $?
@@ -3269,8 +3361,8 @@ def parse_params(action, fullexecution, parameter, self):
32693361
#self.logger.info("Input value: %s" % parameter["value"])
32703362
try:
32713363
parameter["value"] = parameter["value"].replace(escaped_dollar, escape_replacement, -1)
3272-
except:
3273-
self.logger.info("Error in initial replacement of escaped dollar!")
3364+
except Exception as e:
3365+
self.logger.info(f"Error in initial replacement of escaped dollar: {e}")
32743366

32753367
paramname = ""
32763368
try:
@@ -3739,6 +3831,7 @@ def check_branch_conditions(action, fullexecution, self):
37393831
self.logger.info("KeyError body OpenAPI: %s" % e)
37403832
pass
37413833

3834+
# Headache.
37423835
action["parameters"][counter]["value"] = recurse_cleanup_script(action["parameters"][counter]["value"])
37433836

37443837
# This seems redundant now

0 commit comments

Comments
 (0)