Revision 0cdb8b3c ncclient/transport/session.py

b/ncclient/transport/session.py
22 22
logger = logging.getLogger('ncclient.transport.session')
23 23

  
24 24
class Session(Thread):
25
    "This is a base class for use by protocol implementations"
25 26
    
26 27
    def __init__(self, capabilities):
27 28
        Thread.__init__(self)
......
38 39
                     (self, self._client_capabilities))
39 40
    
40 41
    def _dispatch_message(self, raw):
41
        "TODO: docstring"
42 42
        try:
43 43
            root = content.parse_root(raw)
44 44
        except Exception as e:
......
54 54
                logger.warning('[error] %r' % e)
55 55
    
56 56
    def _dispatch_error(self, err):
57
        "TODO: docstring"
58 57
        with self._lock:
59 58
            listeners = list(self._listeners)
60 59
        for l in listeners:
......
87 86
        self.remove_listener(listener)
88 87
        if error[0]:
89 88
            raise error[0]
90
        logger.info('initialized: session-id=%s | server_capabilities=%s' %
91
                     (self._id, self._server_capabilities))
89
        logger.info('initialized: session-id=%s | server_capabilities=%s' % (self._id, self._server_capabilities))
92 90
    
93 91
    def add_listener(self, listener):
92
        """Register a listener that will be notified of incoming messages and errors.
93
        
94
        :type listener: :class:`SessionListener`
95
        """
94 96
        logger.debug('installing listener %r' % listener)
95 97
        if not isinstance(listener, SessionListener):
96 98
            raise SessionError("Listener must be a SessionListener type")
......
98 100
            self._listeners.add(listener)
99 101
    
100 102
    def remove_listener(self, listener):
103
        "Unregister some listener; ignoring if the listener was never registered."
101 104
        logger.debug('discarding listener %r' % listener)
102 105
        with self._lock:
103 106
            self._listeners.discard(listener)
104 107
    
105 108
    def get_listener_instance(self, cls):
109
        """If a listener of the specified type is registered, returns it. This is useful when it is desirable to have only one instance of a particular type per session, i.e. a multiton.
110
        
111
        :type cls: :class:`type`
112
        :rtype: :class:`SessionListener` or :const:`None`
113
        """
106 114
        with self._lock:
107 115
            for listener in self._listeners:
108 116
                if isinstance(listener, cls):
109 117
                    return listener
110 118
    
111
    def connect(self, *args, **kwds):
119
    def connect(self, *args, **kwds): # subclass implements
112 120
        raise NotImplementedError
113 121

  
114
    def run(self):
122
    def run(self): # subclass implements
115 123
        raise NotImplementedError
116 124
    
117 125
    def send(self, message):
126
        """
127
        :param message: XML document
128
        :type message: string
129
        """
118 130
        logger.debug('queueing %s' % message)
119 131
        self._q.put(message)
120 132
    
121 133
    ### Properties
122
    
134

  
135
    @property
136
    def connected(self):
137
        ":rtype: bool"
138
        return self._connected
139

  
123 140
    @property
124 141
    def client_capabilities(self):
142
        ":rtype: :class:`Capabilities`"
125 143
        return self._client_capabilities
126 144
    
127 145
    @property
128 146
    def server_capabilities(self):
147
        ":rtype: :class:`Capabilities` or :const:`None`"
129 148
        return self._server_capabilities
130 149
    
131 150
    @property
132
    def connected(self):
133
        return self._connected
134
    
135
    @property
136 151
    def id(self):
137
        "`session-id` if session is initialized, :const:`None` otherwise"
152
        ":rtype: :obj:`string` or :const:`None`"
138 153
        return self._id
139 154
    
140 155
    @property
141 156
    def can_pipeline(self):
157
        ":rtype: :obj:`bool`"
142 158
        return True
143 159

  
144 160

  
145 161
class SessionListener(object):
146 162
    
163
    """'Listen' to incoming messages on a NETCONF :class:`Session`
164
    
165
    .. note::
166
        Avoid computationally intensive tasks in the callbacks.
167
    """
168
    
147 169
    def callback(self, root, raw):
170
        """Called when a new XML document is received. The `root` argument allows the callback to determine whether it wants to further process the document.
171
        
172
        :param root: tuple of (tag, attrs) where tag is the qualified name of the root element and attrs is a dictionary of its attributes (also qualified names)
173
        :param raw: XML document
174
        :type raw: string
175
        """
148 176
        raise NotImplementedError
149 177
    
150 178
    def errback(self, ex):
179
        """Called when an error occurs.
180
        
181
        :type ex: :class:`Exception`
182
        """
151 183
        raise NotImplementedError
152 184

  
153 185

  

Also available in: Unified diff