Пример #1
0
    def slot(self, event, key=None):
        """
        Returns slot methods connected to the event.

        If signal and slot are connected to specific event by Kiwoom.connect() method,
        then this method returns the connected slot method. If slot is not connected,
        or wrong key is given, this raises a KeyError.

        'key' is needed when hook is set by Kiwoom.set_connect_hook(). 'key' is set to
        be the name of slot method by default unless another string is set on purpose
        when connecting.

        When an event is called, Kiwoom.slot() returns the exact slot method that can
        handle data received from the event. This method is used in Connector decorator
        that wraps events to execute connected slot with the event.

        :param event: str
            One of the pre-defined event names in string. See kiwoom.config.EVENTS.
        :param key: str, optional
            If hook is set by Kiwoom.set_connect_hook() method and slot is connected
            by Kiwoom.connect(), then key is needed. 'key' is set to be name of the
            slot method by default unless another 'key' is given when connecting.
        :return: method or None
            Slot method connected to the given event. If wrong event, returns None.
        """
        if not valid_event(event):
            return None
        if not self.connect_hook(event):
            return self._slots[event]
        return self._slots[event][key]
Пример #2
0
    def signal(self, event, key=None):
        """
        Returns signal methods connected to the event.

        If signal and slot are connected to a specific event by Kiwoom.connect() method,
        then this method returns the connected signal method. If signal is not connected,
        or wrong key is given, raise a KeyError.

        'key' is needed when hook is set by Kiwoom.set_connect_hook(). 'key' is set to
        be the name of signal method by default unless another string is set on purpose
        when connecting.

        When requesting data to server is needed, specifically if more data is available,
        Kiwoom.signal() returns the exact signal method that can request more data.

        :param event: str
            One of the pre-defined event names in string. See kiwoom.config.EVENTS.
        :param key: str, optional
            If hook is set by Kiwoom.set_connect_hook() method and signal is connected
            by Kiwoom.connect(), then key is needed. 'key' is set to be name of the
            signal method by default unless another 'key' is given when connecting.
        :return: method
            Signal method connected to the given event. If wrong event, returns None.
        """
        if not valid_event(event):
            return None
        if not self.connect_hook(event):
            return self._signals[event]
        return self._signals[event][key]
Пример #3
0
    def set_connect_hook(self, event, param):
        """
        Set parameter defined in event as a hook to find the right slot when event is called.

        When an event needs multiple slots to connect, depending on specific tasks, set
        a hook(key) to select which slot to map. The hook must be one of the parameters
        in the definition of the event method. Parameters can be found by help built-in
        function or Kiwoom.api_arg_spec(event). This raises a KeyError if given param is
        not defined in event method.

        If hook is set to the given parameter, argument passed into the parameter when
        the event is called, is going to be a key to connect event, signal and slot.

        Convention is that the name of signal and slot that deal with the related task
        is recommended to be the same, so that 'key' is set to be the method name of
        signal and slot by default. See examples on the tutorials link below.
        https://github.com/breadum/kiwoom/blob/main/tutorials/5.%20TR%20Data.py

        :param event: str
            One of the pre-defined event names in string. See kiwoom.config.EVENTS.
        :param param: str
            Parameter name defined in given event. To see all parameters to event,
            use Kiwoom.api_arg_spec(event) method or help(...) built-in function.
        """
        if not valid_event(event):
            return

        # To check given arg is valid
        from kiwoom import Kiwoom  # lazy import
        args = Kiwoom.api_arg_spec(event)
        if param not in args:
            raise KeyError(f"{param} is not valid.\nSelect one of {args}.")

        # To set connect hook and its index in args
        self._hooks[event] = param
        self._indices[event] = list(
            args.keys()).index(param) - 1  # except 'self'

        # Initialize structure to get signal/slot method by dic[event][key]
        self._signals[event] = dict()
        self._slots[event] = dict()
Пример #4
0
    def connect(self, event, signal=None, slot=None, key=None):
        """
        Connects signals and slots to one of pre-defined events.

        Information saved in this method is used by decorator @Connector() which wraps
        the events and automatically calls the right slot connected to the events. In
        addition to the decorator, Kiwoom.signal(event, key) and Kiwoom.slot(event, key)
        returns the one connected to the event.

        1) If no hook is set on the event, then the connected signal/slot can be retrieved
           by Kiwoom.signal(event) and Kiwoom.slot(event). There is no need to use key.

        2) If hook is set by Kiwoom.set_connect_hook() on the event, in which case there
           needs multiple slots to connect on one event, then connection requires a key
           which is to be the name of signal/slot methods by default.

           The convention to utilizing this module recommends to define the name of related
           signal and slot to be the same. Then it becomes easier to manage and develop codes.

           Use 'key' arg only when there is a special need. The connected signal/slot can be
           retrieved by Kiwoom.signal(event, key='name') and Kiwoom.slot(event, key='name').
           Here 'name' can be a method name or special 'key' used in this method.

        This method checks whether or not given signal/slot can be called without any
        problem. If given method is not bounded to an instance, method should be static
        or lambda function. This is because normally 'self' argument is needed to call
        methods, therefore method must be bounded to an instance unless given method is
        a function.

        Please see tutorials example on the link below.
        https://github.com/breadum/kiwoom/blob/main/tutorials/4.%20TR%20Data.py

        :param event: str
            One of the pre-defined event names in string. See kiwoom.config.EVENTS.
        :param signal: method, optional
            A method that requests to the server
        :param slot: method, optional
            A method that reacts the server's response
        :param key: str, optional
            Key is needed only if hook is set by Kiwoom.set_connect_hook() method.
            Key is set to be name of the given signal and/or slot method by default.
            If key is given other than method name, the connected signal can be
            retrieved by Kiwoom.siganl(event, key) and slot by Kiwoom.slot(event, key)
        """
        valid = False
        connectable = Connector.connectable

        if not valid_event(event):
            return

        # Directly connect slot to the event
        if not self.connect_hook(event):
            # Key can't be used here
            if key is not None:
                raise RuntimeError(
                    "Key can't be used. Remove key argument or Try to set_connect_hook() first."
                )

            elif connectable(signal):
                if connectable(slot):
                    valid = True
                    self._signals[event] = signal
                    self._slots[event] = slot

            elif connectable(slot):
                valid = True
                self._slots[event] = slot

        # Connect slot to the event when
        else:
            if connectable(signal):
                if connectable(slot):
                    valid = True
                    # Key other than method's name
                    if key is not None:
                        self._signals[event][key] = signal
                        self._slots[event][key] = slot
                    # Default key is method's name
                    else:
                        self._signals[event][getattr(signal,
                                                     '__name__')] = signal
                        self._slots[event][getattr(slot, '__name__')] = slot

            elif connectable(slot):
                valid = True
                if key is not None:
                    self._slots[event][key] = slot
                else:
                    self._slots[event][getattr(slot, '__name__')] = slot

        # Nothing is connected
        if not valid:
            raise RuntimeError(
                f"Unsupported combination of inputs. Please read below.\n\n{self.connect.__doc__}"
            )