If you can't read please download the document
Upload
eugene-lopatkin
View
65
Download
0
Embed Size (px)
Citation preview
How to make friends of Python and Win32 API
Connecting the Python to a Win32 API
provided by a stock broker
What was expected
Terms
Real world
?
Issues
COM to pure Python object conversionFlow (events, async methods) handlingMultithreading supportExtensibility
Envisioned solution
Or...
What Ive found
pywin32 package on sourceforge.net by Mark Hammondpython interpreter builds: ActiveState, Anaconda, Canopy with pywin32Python Programming On Win32 by Mark Hammond and Andy Robinsonno actual documentation on activestate.com
Pywin32 workflow
Make Handle Events classMake client object with DispatchWithEvents methodUse API methods on python object
Python client structure
Event class
class ClientEvents: def OnAddBar(self, row, nrows, symbol, interval, datetime, open, high, low, close, volume, open_int): pass # some logic
Client
clnt = client.DispatchWithEvents('COM.Server.1', ClientEvents)clnt.GetBars('SBER', bar_interval, date_time_object, 10)
Cool tool
Make folder python_folder\Lib\site-packages\win32com\gen_pyRun 'win32com\client\makepy.py' (eg, run it from the command window, or double-click on it) and a list will be presented. Select the Type Library.It will generate python wrapper classes from COM Library with all available methods.
Convert DateTime objects
def pytime_2_datetime(pythime): return dt(year=pythime.year, month=pythime.month, day=pythime.day, hour=pythime.hour, minute=pythime.minute, second=pythime.second)def datetime_2_pytime(datetime): return pywintypes.Time(time.mktime(datetime.timetuple()))
Solution v. 0.1
COM to pure Python object conversionFlow (events, async methods) handling
Issues:
Multithreading supportExtensibilityNot stable (?)
Manager
Workflow
Add event queueCreate custom ManagerMake proxy to COM Object
Get pure python Events queue
Use proxy and queue from other threads
Modify Event class, part 1
class ClientEvents: def __init__(self): self.event_queue = Manager().Queue() def get_event_queue(self): return self.event_queue
" " " workflow" - - Modify Event class, part 2
class ClientEvents: def OnAddBar(self, row, nrows, symbol, interval, datetime, open, high, low, close, volume, open_int): self.event_queue.put_nowait(('AddBar', row, nrows, symbol, interval, pytime_2_datetime(datetime), open, high, low, close, volume, open_int))
Use multiprocessing.Manager
class ComManager(BaseManager): pass
Add client method
def get_com_server(): CoInitializeEx(COINIT_MULTITHREADED) clnt = client.DispatchWithEvents('COM.Server.1', ClientEvents) CoUninitialize() return clnt
Register methods
ComManager.register('get_com_server',callable=get_com_server,exposed=('CancelBidAsks', 'CancelOrder', 'GetBars', 'GetMoneyAccount', , 'get_event_queue'))
Fix DateTime bug, part 1
class ClientEvents: def GetBarsSer(self, symbol, interval, since, count): self.GetBars(symbol, interval, datetime_2_pytime(since), count)
Fix DateTime bug, part 2
ComManager.register('get_com_server',callable=get_com_server,exposed=('CancelBidAsks', 'CancelOrder', 'GetBars', 'GetMoneyAccount', , 'get_event_queue', 'GetBarsSer'))
Connection server solution
Use as server, server code
if __name__ == '__main__': freeze_support() m = ComManager(address=('127.0.0.1', port,authkey='authkey').get_server().serve_forever()
Use as server, client code
manager = ComManager(address='address', port, authkey='authkey')manager.connect()com_server =manager.get_com_server()com_event_queue = com_server.get_event_queue()
Stand-alone
In code use
from package_mame import ComManagerif __name__ == '__main__': freeze_support() manager = ComManager() manager.start() com_server = manager.get_com_server() com_event_queue = com_server.get_event_queue()
Solution
v. 0.2
Contacts
Linkedin: https://linkedin.com/in/eugene-lopatkinE-mail: [email protected]
Thank you! Any questions?