how to make friends python with win32 api

Post on 15-Apr-2017

140 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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 conversion● Flow (events, async methods) handling● Multithreading support● Extensibility

Envisioned solution

Or...

What I’ve found

● pywin32 package on sourceforge.net by Mark Hammond● python interpreter builds: ActiveState, Anaconda, Canopy

with pywin32● Python Programming On Win32 by Mark Hammond and

Andy Robinson● no actual documentation on activestate.com

Pywin32 workflow

Make Handle Events class

Make client object with DispatchWithEvents method

Use 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_py

Run '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 conversion

● Flow (events, async methods) handling

Issues:● Multithreading support● Extensibility● Not stable (?)

Manager

Workflow

Add event queue

Create custom Manager

Make 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 …

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()

Solutionv. 0.2

Contacts

Linkedin: https://linkedin.com/in/eugene-lopatkin

E-mail: eugenelopatkin@gmail.com

Thank you! Any questions?

top related