@staticmethod
def generate(filename):

    def init_callback(d: ApiDefinition, m: Callable, cb: str):
        if ((d.callback_methods is not None) or (d.done_method is not None)):
            return f'{current_request_state(d, m)}.{cb} = {cb}'
        return ''

    def init_request_id(d: ApiDefinition, u: Callable):
        if d.uses_req_id:
            return f'{GeneratorUtils.req_id_param_name(d.request_method)} = self.next_request_id()'
        else:
            return ''

    def init_subscription(d: ApiDefinition):
        if (d.cancel_method is None):
            raise RuntimeError(f'Request does not support cancellation {d.request_method.__name__}')
        current_subscription = f'self.{subscription_member_name(d)}[{request_id(d, d.request_method)}]'
        return f'{current_subscription}= SubscriptionGenerator(self.__{d.cancel_method.__name__}, {GeneratorUtils.req_id_param_name(d.request_method)})'

    def async_request_method(d: ApiDefinition, is_subscription: bool):
        method_name = GeneratorUtils.request_method_name(d, is_subscription)
        original_sig = GeneratorUtils.signature(d.request_method)
        signature = GeneratorUtils.request_signature(d, is_subscription)
        param_values = [(p.name if (p.name != d.subscription_flag_name) else f'{(d.subscription_flag_value if is_subscription else (not d.subscription_flag_value))}') for p in original_sig.parameters.values()]
        if is_subscription:
            return f'''

    async def {method_name}{signature}:
        {GeneratorUtils.doc_string(d.request_method)}
        {init_request_id(d, d.request_method)}
        ret: SubscriptionGenerator = None
        with self._lock:
            ret = {init_subscription(d)}
        self._writer.queue.put({bind_method(d, d.request_method, param_values)})
        return ret'''
        if ((d.callback_methods is not None) or (d.done_method is not None)):
            return f'''

    async def {method_name}{signature}:
        {GeneratorUtils.doc_string(d.request_method)}
        loop = asyncio.get_running_loop()
        future = loop.create_future()
        def cb(res: {GeneratorUtils.request_return_type(d, is_subscription)}):
            loop.call_soon_threadsafe(future.set_result, res)
        {init_request_id(d, d.request_method)}
        with self._lock:
            {init_callback(d, d.request_method, 'cb')}
        self._writer.queue.put({bind_method(d, d.request_method, param_values)})
        res = (await future)
        if isinstance(res, IbError):
            raise res
        return res'''
        else:
            return f'''

    async def {method_name}{signature}:
        {GeneratorUtils.doc_string(d.request_method)}
        {init_request_id(d, d.request_method)}
        self._writer.queue.put({bind_method(d, d.request_method, param_values)})
        return None'''

    def cancel_method(d: ApiDefinition):
        return f'''

    def __{GeneratorUtils.method_declaration(d.cancel_method)}:
        {GeneratorUtils.doc_string(d.cancel_method)}
        self.cancel_request({request_id(d, d.cancel_method)})
        self._writer.queue.put({bind_method(d, d.cancel_method, list(GeneratorUtils.signature(d.cancel_method).parameters))})'''
    with open(filename, 'w') as f:
        f.write(f'''
import asyncio
import functools
from collections import defaultdict
from ibapi.client import EClient
from ib_tws_server.asyncio.ib_writer import IBWriter
from ib_tws_server.asyncio.request_state import *
from ib_tws_server.asyncio.subscription_generator import SubscriptionGenerator
from ib_tws_server.error import *
from ib_tws_server.gen.client_responses import *
from ib_tws_server.gen.asyncio_wrapper import *
from ib_tws_server.ib_imports import *
from threading import Lock, Thread
import time
from typing import Callable, Dict, List, Tuple

class AsyncioClient():
    _lock: Lock
    _req_state: Dict[str, RequestState]
    _subscriptions: Dict[int, SubscriptionGenerator]
    _wrapper: AsyncioWrapper
    _client: EClient

    def __init__(self):
        self._lock = Lock()
        self._current_request_id = 0
        self._req_state = defaultdict(RequestState)
        self._subscriptions = defaultdict(SubscriptionGenerator)

        self._wrapper = AsyncioWrapper(self._lock, self._req_state, self._subscriptions)
        self._client = EClient(self._wrapper)
        self._writer = IBWriter(self._client)
        self._wrapper._writer = self._writer

    def run(self):
        self._writer.start()
        self._client.run()

    def next_request_id(self):
        with self._lock:
            self._current_request_id += 1
            return self._current_request_id

    def disconnect(self, clean=False):
        self._wrapper._expecting_disconnect = clean
        return self._client.disconnect()

    def cancel_request(self, id: RequestId):
        response_cb = None
        with self._lock:
            if id in self._req_state:
                response_cb = self._req_state[id].cb
                del self._req_state[id]
            if id in self._subscriptions:
                del self._subscriptions[id]
        if response_cb is not None:
            response_cb(None)

    def start(self, host: str, port: int, client_id: int, connection_retry_interval: int):
        while True:
            try:
                self._client.connect(host, port, client_id)
                break
            except ConnectionError as e:
                if connection_retry_interval > 0:
                    time.sleep(connection_retry_interval)
                else:
                    raise e

        thread = Thread(target = self.run)
        thread.start()
        setattr(thread, "_thread", thread)

    def active_request_count(self):
        with self._lock:
            return len(self._req_state) 

    def active_subscription_count(self):
        with self._lock:
            return len(self._subscriptions) 
''')
        for d in REQUEST_DEFINITIONS:
            if (d.request_method is not None):
                if (d.subscription_flag_name is not None):
                    f.write(async_request_method(d, False))
                    f.write(async_request_method(d, True))
                else:
                    f.write(async_request_method(d, d.is_subscription))
                if ((d.cancel_method is not None) and (d.is_subscription or (d.subscription_flag_name is not None))):
                    f.write(cancel_method(d))
@staticmethod
def generate(filename):

    def init_callback(d: ApiDefinition, m: Callable, cb: str):
        if ((d.callback_methods is not None) or (d.done_method is not None)):
            return f'{current_request_state(d, m)}.{cb} = {cb}'
        return 

    def init_request_id(d: ApiDefinition, u: Callable):
        if d.uses_req_id:
            return f'{GeneratorUtils.req_id_param_name(d.request_method)} = self.next_request_id()'
        else:
            return 

    def init_subscription(d: ApiDefinition):
        if (d.cancel_method is None):
            raise RuntimeError(f'Request does not support cancellation {d.request_method.__name__}')
        current_subscription = f'self.{subscription_member_name(d)}[{request_id(d, d.request_method)}]'
        return f'{current_subscription}= SubscriptionGenerator(self.__{d.cancel_method.__name__}, {GeneratorUtils.req_id_param_name(d.request_method)})'

    def async_request_method(d: ApiDefinition, is_subscription: bool):
        method_name = GeneratorUtils.request_method_name(d, is_subscription)
        original_sig = GeneratorUtils.signature(d.request_method)
        signature = GeneratorUtils.request_signature(d, is_subscription)
        param_values = [(p.name if (p.name != d.subscription_flag_name) else f'{(d.subscription_flag_value if is_subscription else (not d.subscription_flag_value))}') for p in original_sig.parameters.values()]
        if is_subscription:
            return f'

    async def {method_name}{signature}:
        {GeneratorUtils.doc_string(d.request_method)}
        {init_request_id(d, d.request_method)}
        ret: SubscriptionGenerator = None
        with self._lock:
            ret = {init_subscription(d)}
        self._writer.queue.put({bind_method(d, d.request_method, param_values)})
        return ret'
        if ((d.callback_methods is not None) or (d.done_method is not None)):
            return f'

    async def {method_name}{signature}:
        {GeneratorUtils.doc_string(d.request_method)}
        loop = asyncio.get_running_loop()
        future = loop.create_future()
        def cb(res: {GeneratorUtils.request_return_type(d, is_subscription)}):
            loop.call_soon_threadsafe(future.set_result, res)
        {init_request_id(d, d.request_method)}
        with self._lock:
            {init_callback(d, d.request_method, 'cb')}
        self._writer.queue.put({bind_method(d, d.request_method, param_values)})
        res = (await future)
        if isinstance(res, IbError):
            raise res
        return res'
        else:
            return f'

    async def {method_name}{signature}:
        {GeneratorUtils.doc_string(d.request_method)}
        {init_request_id(d, d.request_method)}
        self._writer.queue.put({bind_method(d, d.request_method, param_values)})
        return None'

    def cancel_method(d: ApiDefinition):
        return f'

    def __{GeneratorUtils.method_declaration(d.cancel_method)}:
        {GeneratorUtils.doc_string(d.cancel_method)}
        self.cancel_request({request_id(d, d.cancel_method)})
        self._writer.queue.put({bind_method(d, d.cancel_method, list(GeneratorUtils.signature(d.cancel_method).parameters))})'
    with open(filename, 'w') as f:
        f.write(f'
import asyncio
import functools
from collections import defaultdict
from ibapi.client import EClient
from ib_tws_server.asyncio.ib_writer import IBWriter
from ib_tws_server.asyncio.request_state import *
from ib_tws_server.asyncio.subscription_generator import SubscriptionGenerator
from ib_tws_server.error import *
from ib_tws_server.gen.client_responses import *
from ib_tws_server.gen.asyncio_wrapper import *
from ib_tws_server.ib_imports import *
from threading import Lock, Thread
import time
from typing import Callable, Dict, List, Tuple

class AsyncioClient():
    _lock: Lock
    _req_state: Dict[str, RequestState]
    _subscriptions: Dict[int, SubscriptionGenerator]
    _wrapper: AsyncioWrapper
    _client: EClient

    def __init__(self):
        self._lock = Lock()
        self._current_request_id = 0
        self._req_state = defaultdict(RequestState)
        self._subscriptions = defaultdict(SubscriptionGenerator)

        self._wrapper = AsyncioWrapper(self._lock, self._req_state, self._subscriptions)
        self._client = EClient(self._wrapper)
        self._writer = IBWriter(self._client)
        self._wrapper._writer = self._writer

    def run(self):
        self._writer.start()
        self._client.run()

    def next_request_id(self):
        with self._lock:
            self._current_request_id += 1
            return self._current_request_id

    def disconnect(self, clean=False):
        self._wrapper._expecting_disconnect = clean
        return self._client.disconnect()

    def cancel_request(self, id: RequestId):
        response_cb = None
        with self._lock:
            if id in self._req_state:
                response_cb = self._req_state[id].cb
                del self._req_state[id]
            if id in self._subscriptions:
                del self._subscriptions[id]
        if response_cb is not None:
            response_cb(None)

    def start(self, host: str, port: int, client_id: int, connection_retry_interval: int):
        while True:
            try:
                self._client.connect(host, port, client_id)
                break
            except ConnectionError as e:
                if connection_retry_interval > 0:
                    time.sleep(connection_retry_interval)
                else:
                    raise e

        thread = Thread(target = self.run)
        thread.start()
        setattr(thread, "_thread", thread)

    def active_request_count(self):
        with self._lock:
            return len(self._req_state) 

    def active_subscription_count(self):
        with self._lock:
            return len(self._subscriptions) 
')
        for d in REQUEST_DEFINITIONS:
            if (d.request_method is not None):
                if (d.subscription_flag_name is not None):
                    f.write(async_request_method(d, False))
                    f.write(async_request_method(d, True))
                else:
                    f.write(async_request_method(d, d.is_subscription))
                if ((d.cancel_method is not None) and (d.is_subscription or (d.subscription_flag_name is not None))):
                    f.write(cancel_method(d))