Skip to content

Commit

Permalink
Improve python command serialization (#8351)
Browse files Browse the repository at this point in the history
- Fix bug in python command serialization, expanding existing tests
  • Loading branch information
Martin-Molinero authored Oct 2, 2024
1 parent 8fb70b2 commit 7c9aa85
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
14 changes: 14 additions & 0 deletions Algorithm.Python/CallbackCommandRegressionAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def get_quantity(self):
return self.quantity

class BoolCommand(Command):
something_else = {}
array_test = []
result = False

def run(self, algo: QCAlgorithm) -> bool | None:
Expand Down Expand Up @@ -69,15 +71,27 @@ def initialize(self):
if not threw_exception:
raise ValueError('InvalidCommand did not throw!')

bool_command = BoolCommand()
bool_command.result = True
bool_command.something_else = { "Property": 10 }
bool_command.array_test = [ "SPY", "BTCUSD" ]
link = self.link(bool_command)
if "&command[array_test][0]=SPY&command[array_test][1]=BTCUSD&command[result]=True&command[something_else][Property]=10&command[$type]=BoolCommand" not in link:
raise ValueError(f'Invalid link was generated! {link}')

potential_command = VoidCommand()
potential_command.target = [ "BAC" ]
potential_command.quantity = 10
potential_command.parameters = { "tag": "Signal X" }

command_link = self.link(potential_command)
if "command[target][0]=BAC&command[quantity]=10&command[parameters][tag]=Signal+X&command[$type]=VoidCommand" not in command_link:
raise ValueError(f'Invalid link was generated! {command_link}')
self.notify.email("email@address", "Trade Command Event", f"Signal X trade\nFollow link to trigger: {command_link}")

untyped_command_link = self.link({ "symbol": "SPY", "parameters": { "quantity": 10 } })
if "&command[symbol]=SPY&command[parameters][quantity]=10" not in untyped_command_link:
raise ValueError(f'Invalid link was generated! {untyped_command_link}')
self.notify.email("email@address", "Untyped Command Event", f"Signal Y trade\nFollow link to trigger: {untyped_command_link}")

def on_command(self, data):
Expand Down
2 changes: 1 addition & 1 deletion Common/Commands/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public object GetProperty(string name)
return fieldInfo.GetValue(this);
}
}
throw new KeyNotFoundException($"Property with name \'{name}\' does not exist. Properties: {string.Join(", ", _storage.Keys)}");
return null;
}
return value;
}
Expand Down
20 changes: 17 additions & 3 deletions Common/Python/CommandPythonWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public CommandPythonWrapper(PyObject type, string data = null)
/// <returns>True if success, false otherwise. Returning null will disable command feedback</returns>
public bool? Run(IAlgorithm algorithm)
{
using var _ = Py.GIL();
var result = InvokeMethod(nameof(Run), algorithm);
return result.GetAndDispose<bool?>();
}
Expand All @@ -88,18 +89,31 @@ public static string Serialize(PyObject command)
return string.Empty;
}

using var _ = Py.GIL();
if (_linkSerializationMethod == null)
{
var module = PyModule.FromString("python_serialization", @"from json import dumps
from inspect import getmembers
def serialize(target):
if not hasattr(target, '__dict__'):
# for example dictionaries
if isinstance(target, dict):
# dictionary
return dumps(target)
if not hasattr(target, '__dict__') or not target.__dict__:
# python command inheriting base Command
members = getmembers(target)
result = {}
for name, value in members:
if value and not name.startswith('__'):
potential_entry = str(value)
if not potential_entry.startswith('<bound '):
result[name] = value
return dumps(result)
# pure python command object
return dumps(target.__dict__)
");
_linkSerializationMethod = module.GetAttr("serialize");
}
using var _ = Py.GIL();
using var strResult = _linkSerializationMethod.Invoke(command);

return strResult.As<string>();
Expand Down

0 comments on commit 7c9aa85

Please sign in to comment.