File: observer.py

package info (click to toggle)
python-pysnmp4 7.1.21-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,564 kB
  • sloc: python: 33,654; makefile: 166; javascript: 4
file content (108 lines) | stat: -rw-r--r-- 3,920 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#
# This file is part of pysnmp software.
#
# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com>
# License: https://www.pysnmp.com/pysnmp/license.html
#
from typing import TYPE_CHECKING


from pysnmp import error

if TYPE_CHECKING:
    from pysnmp.entity.engine import SnmpEngine


class MetaObserver:
    r"""This is a simple facility for exposing internal SNMP Engine working details to pysnmp applications.

    These details are basically local scope variables at a fixed point of
    execution. Two modes of operations are offered:

    1. Consumer: app can request an execution point context by execution point ID.
    2. Provider: app can register its callback function (and context) to be invoked
       once execution reaches specified point. All local scope variables
       will be passed to the callback as in #1.

    It's important to realize that execution context is only guaranteed
    to exist to functions that are at the same or deeper level of invocation
    relative to execution point specified.
    """

    def __init__(self):
        """Create a meta observer instance."""
        self.__observers = {}
        self.__contexts = {}
        self.__execpoints = {}

    def register_observer(self, cbFun, *execpoints, **kwargs):
        """Register a callback function to be invoked at specified execution points.

        Args:
            cbFun (callable): Callback function to be invoked.
            execpoints (str): Execution point ID(s) to trigger the callback.
            cbCtx (object): Arbitrary object to be passed to the callback.

        Raises:
            PySnmpError: If observer is already registered.
        """
        if cbFun in self.__contexts:
            raise error.PySnmpError("duplicate observer %s" % cbFun)
        else:
            self.__contexts[cbFun] = kwargs.get("cbCtx")
        for execpoint in execpoints:
            if execpoint not in self.__observers:
                self.__observers[execpoint] = []
            self.__observers[execpoint].append(cbFun)

    def unregister_observer(self, cbFun=None):
        """Unregister a callback function.

        Args:
            cbFun (callable): Callback function to be unregistered. If not specified,
                all observers will be unregistered.
        """
        if cbFun is None:
            self.__observers.clear()
            self.__contexts.clear()
        else:
            for execpoint in dict(self.__observers):
                if cbFun in self.__observers[execpoint]:
                    self.__observers[execpoint].remove(cbFun)
                if not self.__observers[execpoint]:
                    del self.__observers[execpoint]

    def store_execution_context(self, snmpEngine: "SnmpEngine", execpoint, variables):
        """Store execution context at specified execution point.

        Args:
            execpoint (str): Execution point ID.
            variables (dict): Local scope variables to store.
        """
        self.__execpoints[execpoint] = variables
        if execpoint in self.__observers:
            for cbFun in self.__observers[execpoint]:
                cbFun(snmpEngine, execpoint, variables, self.__contexts[cbFun])

    def clear_execution_context(self, snmpEngine: "SnmpEngine", *execpoints):
        """Clear execution context at specified execution points.

        Args:
            execpoints (str): Execution point ID(s) to clear.
        """
        if execpoints:
            for execpoint in execpoints:
                del self.__execpoints[execpoint]
        else:
            self.__execpoints.clear()

    def get_execution_context(self, execpoint):
        """Retrieve execution context at specified execution point.

        Args:
            execpoint (str): Execution point ID.

        Returns:
            dict: Local scope variables at the specified execution point.
        """
        return self.__execpoints[execpoint]