### Example: Get interface description Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/smi.md Demonstrates using `withIndex` to construct an OID for a specific interface and retrieving its description using a manager's `get` method. ```python ifDescr = OID.parse("1.3.6.1.2.1.2.2.1.2") vb, = manager.get(ifDescr.withIndex(Integer(3))) print(f"Description: {vb.value.data}") ``` -------------------------------- ### SNMPv3 Asynchronous Example Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/index.md This example shows how to perform SNMPv3 GET requests using the asynchronous engine. It requires setting up the user with authentication and privacy protocols. ```python import asyncio from snmp.async_engine import AsyncEngine from snmp.security.usm.auth import HmacSha512 from snmp.security.usm.priv import AesCfb128 engine = AsyncEngine() engine.addUser( "authPrivUser", authProtocol=HmacSha512, authSecret=b"myauthphrase", privProtocol=AesCfb128, privSecret=b"myprivphrase", ) async def main(manager): response = await manager.get("1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.6.0") print(response) loop = asyncio.get_event_loop() localhost = engine.Manager("127.0.0.1") loop.run_until_complete(main(localhost)) ``` -------------------------------- ### SNMPv3 Synchronous Example Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/index.md This example demonstrates adding a user with authentication and privacy protocols and then performing a GET request. Ensure snmpd is configured correctly with the specified user and secrets. ```python from snmp import Engine from snmp.security.usm.auth import HmacSha512 from snmp.security.usm.priv import AesCfb128 engine = Engine() engine.addUser( "authPrivUser", authProtocol=HmacSha512, authSecret=b"myauthphrase", privProtocol=AesCfb128, privSecret=b"myprivphrase", ) localhost = engine.Manager("127.0.0.1") response = localhost.get("1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.6.0") print(response) ``` -------------------------------- ### Install Python SNMP Library Source: https://context7.com/charlestolley/python-snmp/llms.txt Install the library using pip. For OpenSSL-backed privacy, follow the additional steps. ```console pip install snmp pip install -r snmp/cffi/requirements.txt python -c "from snmp.cffi.openssl import ffi; ffi.compile()" # Ubuntu: sudo apt install libssl-dev (if OpenSSL headers are missing) ``` -------------------------------- ### Perform SNMP GET Request Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/getting_started.md Combine engine setup, user addition, manager creation, and a GET request to query sysContact and sysLocation OIDs. Ensure snmpd is installed and configured if running on Ubuntu. ```python from snmp import Engine from snmp.security.usm.auth import HmacSha512 from snmp.security.usm.priv import AesCfb128 engine = Engine() engine.addUser( "authPrivUser", authProtocol=HmacSha512, authSecret=b"myauthphrase", privProtocol=AesCfb128, privSecret=b"myprivphrase", ) localhost = engine.Manager("127.0.0.1") response = localhost.get("1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.6.0") print(response) ``` -------------------------------- ### Install OpenSSL headers on Ubuntu Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/installation.md On Ubuntu systems, OpenSSL headers can be installed using the apt package manager. This is often required for the CFFI compilation to succeed. ```bash sudo apt install libssl-dev ``` -------------------------------- ### Install Python SNMP Library Source: https://github.com/charlestolley/python-snmp/blob/develop/README.md Install the library using pip. This is the standard method for adding Python packages to your project. ```bash pip install snmp ``` -------------------------------- ### Synchronous vs. Asynchronous Get Request Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/manager.md Demonstrates two equivalent ways to make a Get request and await the response. The first is synchronous, while the second uses wait=False and then calls wait() on the returned RequestHandle. ```python vblist = manager.get("1.3.6.1.2.1.1.1.0", wait=True) vblist = manager.get("1.3.6.1.2.1.1.1.0", wait=False).wait() ``` -------------------------------- ### Install cffi for OpenSSL support Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/installation.md To enable the OpenSSL implementation for SNMPv3 encryption, first install the cffi library using the provided requirements file. ```bash pip install -r snmp/cffi/requirements.txt ``` -------------------------------- ### SNMPv3 Security Protocols Configuration Source: https://context7.com/charlestolley/python-snmp/llms.txt Shows how to configure authentication and privacy protocols for SNMPv3 users using the `addUser` method. It includes examples for recommended strong security (SHA-512 with AES-128), auth-only (SHA-256), and unauthenticated (noAuthNoPriv) setups. ```python from snmp import Engine # Authentication protocols (snmp.security.usm.auth) from snmp.security.usm.auth import ( HmacMd5, # HMAC-MD5-96 (RFC 3414 §6) — legacy, avoid if possible HmacSha, # HMAC-SHA-96 (RFC 3414 §7) — legacy HmacSha224, # HMAC-SHA-224 (RFC 7860) HmacSha256, # HMAC-SHA-256 (RFC 7860) HmacSha384, # HMAC-SHA-384 (RFC 7860) HmacSha512, # HMAC-SHA-512 (RFC 7860) — strongest, recommended ) # Privacy protocols (snmp.security.usm.priv) — requires pycryptodome or OpenSSL from snmp.security.usm.priv import ( AesCfb128, # CFB128-AES-128 (RFC 3826 §3) — recommended DesCbc, # CBC-DES (RFC 3414 §8) — legacy, avoid ) engine = Engine() # Recommended: SHA-512 auth + AES-128 priv engine.addUser("secure-user", authProtocol=HmacSha512, privProtocol=AesCfb128, secret=b"strongpassphrase") # Auth-only (no encryption): SHA-256 engine.addUser("auth-only-user", authProtocol=HmacSha256, secret=b"authpassphrase") # noAuthNoPriv (unauthenticated — SNMPv3 discovery or open agents) engine.addUser("open-user", authProtocol=None, privProtocol=None, secret=None, defaultSecurityLevel=snmp.noAuthNoPriv) ``` -------------------------------- ### Engine - Core Functionality Source: https://context7.com/charlestolley/python-snmp/llms.txt Demonstrates the initialization of an SNMP Engine and the creation of a Manager object to interact with a local agent. It shows how to add SNMPv3 users and perform a GET request. ```APIDOC ## Engine - `snmp.Engine` The `Engine` class is the entry point for all SNMP operations. It manages transport sockets, USM security state, user credentials, and request multiplexing. Only one `Engine` instance is needed per application. It is not thread-safe; all Manager and RequestHandle calls must occur in a single thread. ```python import logging import snmp from snmp.security.usm.auth import HmacSha512 from snmp.security.usm.priv import AesCfb128 # Enable verbose logging of discarded packets logging.basicConfig(level=logging.DEBUG) engine = snmp.Engine( defaultVersion=snmp.SNMPv3, # default: SNMPv3 defaultDomain=snmp.UDP_IPv4, # default: UDP_IPv4 defaultCommunity=b"public", # default community for v1/v2c autowait=True, # block on each request by default verboseLogging=True, # log discarded packets via logging.debug ) # Add a SNMPv3 user with auth+priv engine.addUser( "authPrivUser", authProtocol=HmacSha512, authSecret=b"myauthphrase", privProtocol=AesCfb128, privSecret=b"myprivphrase", ) # Create a manager targeting a specific host localhost = engine.Manager("127.0.0.1") response = localhost.get("1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.6.0") print(response) # 1.3.6.1.2.1.1.4.0: OctetString(b'Me ') # 1.3.6.1.2.1.1.6.0: OctetString(b'Sitting on the Dock of the Bay') ``` ``` -------------------------------- ### SNMP Set Request Example Source: https://context7.com/charlestolley/python-snmp/llms.txt Demonstrates how to send an SNMP Set request to update variables on a remote agent. Values must be typed snmp.smi instances. Includes examples for atomic updates and error handling for responses like 'notWritable' or timeouts. ```python from snmp import Engine from snmp.smi import OctetString, Integer32, IpAddress engine = Engine() engine.addUser("admin", authProtocol=..., secret=b"secret") manager = engine.Manager("192.168.1.1") # Update sysContact and sysLocation atomically vblist = manager.set( ("1.3.6.1.2.1.1.4.0", OctetString(b"ops@example.com")), ("1.3.6.1.2.1.1.6.0", OctetString(b"Server Room B, Rack 3")), ) print("Set successful:", vblist) # Set with error handling from snmp import ErrorResponse, Timeout try: manager.set(("1.3.6.1.2.1.1.4.0", OctetString(b"new-contact"))) except ErrorResponse as err: print(f"Set failed: {err.status.name}") # e.g. "notWritable", "wrongType" except Timeout: print("Set request timed out") ``` -------------------------------- ### Parallel Get Requests Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/manager.md Shows how to send multiple Get requests in parallel by using wait=False for each request and then calling wait() on their respective RequestHandles. This is more efficient than sending requests sequentially. ```python handle1 = manager1.get("1.3.6.1.2.1.1.1.0", wait=False) handle2 = manager2.get("1.3.6.1.2.1.1.1.0", wait=False) handle3 = manager3.get("1.3.6.1.2.1.1.1.0", wait=False) vblist1 = handle1.wait() vblist2 = handle2.wait() vblist3 = handle3.wait() ``` -------------------------------- ### Sequential Get Requests Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/manager.md Illustrates sending Get requests sequentially, where each request is sent only after the manager receives the response to the previous one. This method is significantly slower than parallel requests. ```python vblist1 = manager1.get("1.3.6.1.2.1.1.1.0", wait=True) vblist2 = manager2.get("1.3.6.1.2.1.1.1.0", wait=True) vblist3 = manager3.get("1.3.6.1.2.1.1.1.0", wait=True) ``` -------------------------------- ### Perform Asynchronous SNMP GET Request Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/getting_started_legacy.md Utilize the AsyncEngine for non-blocking SNMP operations. This example demonstrates an asynchronous GET request within an asyncio event loop. ```python import asyncio from snmp import * from snmp.async_engine import AsyncEngine async def main(manager): response = await manager.get("1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.6.0") print(response) engine = AsyncEngine(SNMPv1) # or SNMPv2c localhost = engine.Manager("127.0.0.1", community=b"public") loop = asyncio.get_event_loop() loop.run_until_complete(main(localhost)) ``` -------------------------------- ### Get Request with Timeout and Refresh Period (Asynchronous) Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/manager.md Example of an asynchronous Get request with a short refresh period and a timeout. The application code execution is blocked by time.sleep(), preventing the Engine from re-sending the request within the specified refresh period. ```python handle = manager.get("1.3.6.1.2.1.1.1.0", refreshPeriod=0.5, timeout=2.5, wait=False) time.sleep(3.0) vblist = handle.wait() ``` -------------------------------- ### Check OID prefix Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/smi.md Checks if the OID starts with a given prefix OID, similar to str.startswith(). ```python startswith(prefix: OID) ``` -------------------------------- ### set() method Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/library.md Send an SNMP Set request, and await the response. The behavior of this method is the same as the `get()` method, aside from the request type and the format of the positional arguments. The varbinds argument(s) may be either a `(name, value)` tuple, or a `VarBind`. The `name` element accepts either a `str` or an `OID`, just like the *oids argument list to the `get()` method. The `value` element must be an instance of one of the classes defined in `snmp.smi`. ```APIDOC ## set(*varbinds: [VarBind](smi.md#snmp.smi.VarBind) | tuple, timeout: float = 10.0) ### Description Send an SNMP Set request, and await the response. The behavior of this method is the same as the `get()` method, aside from the request type and the format of the positional arguments. ### Parameters #### Varbinds - `*varbinds`: A variable number of arguments, where each argument is either a `VarBind` object or a tuple of `(name, value)`. - `name`: Can be a `str` or an `OID`. - `value`: Must be an instance of a class defined in `snmp.smi`. - `timeout`: The timeout in seconds for the request. Defaults to 10.0. ### Request Example ```python name = "1.3.6.1.2.1.1.1.0" value = OctetString(b"New system description") vblist = manager.set((name, value)) ``` ``` -------------------------------- ### get() Method Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/manager.md Retrieves SNMP variables from a device. It performs checks to ensure the response matches the request and can raise exceptions for various issues. ```APIDOC ## get(*oids, timeout=10.0, refreshPeriod=1.0, wait=None) ### Description Retrieves SNMP variables from a device based on the provided Object Identifiers (OIDs). ### Parameters - **oids**: Variable length list of OIDs to query. - **timeout** (float, optional): The maximum time to wait for a response. Defaults to 10.0 seconds. - **refreshPeriod** (float, optional): The period for refreshing data. Defaults to 1.0 seconds. - **wait** (any, optional): Parameter to control waiting behavior. Its specific type and usage are not detailed. ### Exceptions - **snmp.ImproperResponse**: Raised if the response variables do not match the requested OIDs in order. The `VarBindList` is accessible via the `variableBindings` attribute. - **Exception**: Catches broader exceptions, often related to SNMPv3 security credentials or other unexpected issues. It is recommended to catch these to log or report problems to a human. ``` -------------------------------- ### Get Request with Timeout and Refresh Period (Asynchronous, Detailed Timing) Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/manager.md Illustrates the timing of re-sending requests and timeouts in an asynchronous Get request. The request is re-sent at specified intervals if no response is received, and a Timeout exception is raised if the total timeout duration is exceeded. ```python handle = manager.get("1.3.6.1.2.1.1.1.0", refreshPeriod=1.0, timeout=3.0, wait=False) time.sleep(1.5) vblist = handle.wait() ``` -------------------------------- ### Send SNMP GetBulk Request with Non-Repeaters Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/manager.md This example demonstrates using getBulk with nonRepeaters to include specific OIDs that are not part of the repeated query. This is useful for attaching contextual information like timestamps to the bulk data. ```python vblist = manager.getBulk( sysUpTime, ifDescr, ifInOctets, nonRepeaters=1, maxRepetitions=2, ) print(vblist) ``` -------------------------------- ### Perform SNMP GetNext Requests for MIB Walking Source: https://context7.com/charlestolley/python-snmp/llms.txt Execute SNMP GetNext requests to retrieve variables lexicographically following specified OIDs. This is useful for traversing tables and performing MIB walks. Includes an example of manual MIB walking until EndOfMibView. ```python from snmp import Engine from snmp.smi import OID, Integer engine = Engine() engine.addUser("admin", authProtocol=..., secret=b"secret") manager = engine.Manager("192.168.1.1") # Walk the ifDescr column to find the first interface ifDescr = OID.parse("1.3.6.1.2.1.2.2.1.2") vb, = manager.getNext(ifDescr) # Decode the index from the returned OID index = vb.name.getIndex(ifDescr).value description = vb.value.data.decode() print(f"Interface {index}: {description}") # Interface 1: eth0 # Manual MIB walk — keep calling getNext until EndOfMibView from snmp.smi import EndOfMibView current = ifDescr while True: vb, = manager.getNext(current) if not vb.name.startswith(ifDescr) or isinstance(vb.value, EndOfMibView): break current = vb.name print(f" {vb.name}: {vb.value.data.decode()}") ``` -------------------------------- ### Perform SNMP GET Request Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/getting_started_legacy.md Send a GET request to retrieve sysContact and sysLocation OIDs from a remote engine. Ensure the snmpd daemon is installed and running. ```python from snmp import * engine = Engine(SNMPv1) # or SNMPv2c localhost = engine.Manager("127.0.0.1", community=b"public") response = localhost.get("1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.6.0") print(response) ``` -------------------------------- ### Initialize SNMP Engine and Add User Source: https://context7.com/charlestolley/python-snmp/llms.txt Configure the SNMP engine with default settings and add a SNMPv3 user with authentication and privacy protocols. A Manager is then created to communicate with a local agent. ```python import logging import snmp from snmp.security.usm.auth import HmacSha512 from snmp.security.usm.priv import AesCfb128 # Enable verbose logging of discarded packets logging.basicConfig(level=logging.DEBUG) engine = snmp.Engine( defaultVersion=snmp.SNMPv3, # default: SNMPv3 defaultDomain=snmp.UDP_IPv4, # default: UDP_IPv4 defaultCommunity=b"public", # default community for v1/v2c autowait=True, # block on each request by default verboseLogging=True, # log discarded packets via logging.debug ) # Add a SNMPv3 user with auth+priv engine.addUser( "authPrivUser", authProtocol=HmacSha512, authSecret=b"myauthphrase", privProtocol=AesCfb128, privSecret=b"myprivphrase", ) # Create a manager targeting a specific host localhost = engine.Manager("127.0.0.1") response = localhost.get("1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.6.0") print(response) # 1.3.6.1.2.1.1.4.0: OctetString(b'Me ') # 1.3.6.1.2.1.1.6.0: OctetString(b'Sitting on the Dock of the Bay') ``` -------------------------------- ### Add SNMPv3 Users and Create Managers Source: https://context7.com/charlestolley/python-snmp/llms.txt Demonstrates how to add users with different authentication and privacy protocols for distinct namespaces. Managers are then created using these credentials to interact with devices within their respective namespaces. ```python engine.addUser("admin", namespace="datacenter", authProtocol=HmacSha512, privProtocol=AesCfb128, secret=b"dc-secret") engine.addUser("admin", namespace="branch", authProtocol=HmacSha256, secret=b"branch-secret") dc_switch = engine.Manager("10.1.0.1", namespace="datacenter") dc_router = engine.Manager("10.1.0.254", namespace="datacenter") branch_ap = engine.Manager("10.2.0.1", namespace="branch") for m in [dc_switch, dc_router, branch_ap]: vblist = m.get("1.3.6.1.2.1.1.5.0") print(vblist) ``` -------------------------------- ### Instantiate SNMP Engine with Verbose Logging Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/engine.md Configure logging and instantiate the Engine with verbose logging enabled to see detailed messages for discarded packets. Ensure logging is configured before creating the Engine. ```python import logging import snmp logging.basicConfig(level=logging.DEBUG) engine = snmp.Engine(verboseLogging=True) ``` -------------------------------- ### Create SNMP Managers with Different Configurations Source: https://context7.com/charlestolley/python-snmp/llms.txt Instantiate SNMP managers with various versions (SNMPv1, SNMPv2c, SNMPv3), security settings (community strings), network protocols (UDP/IPv6), custom MTU, and local bind addresses. ```python switch = engine.Manager(("2001:db8::1", 1161), version=SNMPv3, domain=UDP_IPv6) ``` ```python printer = engine.Manager("10.0.0.5", version=SNMPv2c, community=b"private") ``` ```python legacy = engine.Manager("10.0.0.99", version=SNMPv1, community=b"public") ``` ```python managed = engine.Manager( "10.0.0.10", localAddress=("192.168.1.100", 0), # bind to specific local IP, random port mtu=9000, # jumbo frames autowait=False # default to non-blocking requests ) ``` -------------------------------- ### Namespaces for Multi-Credential Network Management Source: https://context7.com/charlestolley/python-snmp/llms.txt Illustrates the namespace model, enabling a single `Engine` to manage devices with different SNMPv3 credentials by grouping devices into named namespaces and associating credentials with them. ```python from snmp import Engine from snmp.security.usm.auth import HmacSha256, HmacSha512 from snmp.security.usm.priv import AesCfb128 engine = Engine() ``` -------------------------------- ### Get Request with Short Timeout (Synchronous) Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/manager.md A synchronous Get request configured with a refresh period longer than the timeout. This will result in a Timeout exception before any re-send attempts are made. ```python vblist = manager.get("1.3.6.1.2.1.1.1.0", refreshPeriod=1.5, timeout=1.0, wait=True) ``` -------------------------------- ### Initialize SNMP Engine Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/getting_started_legacy.md Create an Engine object specifying the SNMP version to be used. The default community string is 'public'. ```python from snmp import Engine, SNMPv1 engine = Engine(SNMPv1) ``` -------------------------------- ### Compile OpenSSL CFFI module Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/installation.md After installing cffi, compile the OpenSSL CFFI module within a Python interactive shell. Ensure OpenSSL headers are installed if compilation fails. ```python >>> from snmp.cffi.openssl import ffi >>> ffi.compile() ``` -------------------------------- ### Perform SNMP Get Requests Source: https://context7.com/charlestolley/python-snmp/llms.txt Send SNMP Get requests for one or more OIDs. Supports blocking and non-blocking operations, with comprehensive error handling for common SNMP exceptions like NoSuchName, ErrorResponse, and Timeout. ```python from snmp import Engine, Timeout, ErrorResponse, NoSuchName from snmp.security.usm.auth import HmacSha512 from snmp.security.usm.priv import AesCfb128 engine = Engine() engine.addUser("admin", authProtocol=HmacSha512, authSecret=b"auth", privProtocol=AesCfb128, privSecret=b"priv") manager = engine.Manager("192.168.1.1") # Blocking get of two OIDs vblist = manager.get("1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.3.0") descr = vblist[0].value.data.decode() # OctetString -> bytes -> str uptime = vblist[1].value.value / 100 # TimeTicks (1/100 s) -> seconds print(f"Description: {descr!r}") print(f"Uptime: {uptime:.1f} seconds") # With full error handling try: vblist = manager.get("1.3.6.1.2.1.1.1.0", timeout=5.0) except NoSuchName as err: print(f"noSuchName at index {err.index}") except ErrorResponse as err: print(f"SNMP error: {err.status.name}") except Timeout: print("Request timed out") except Exception as err: print(f"Unexpected error (check credentials): {err}") # Non-blocking: send three requests in parallel, then collect results h1 = manager.get("1.3.6.1.2.1.1.1.0", wait=False) h2 = manager.get("1.3.6.1.2.1.1.3.0", wait=False) h3 = manager.get("1.3.6.1.2.1.1.5.0", wait=False) r1, r2, r3 = h1.wait(), h2.wait(), h3.wait() ``` -------------------------------- ### snmp.Engine Constructor Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/engine.md Instantiates an Engine object. It's recommended to only have one Engine instance. The constructor accepts keyword-only arguments for default version, domain, community, and autowait settings. The verboseLogging parameter enables detailed logging for discarded packets. ```APIDOC ## _class_ snmp.Engine(defaultVersion: SNMPv1 | SNMPv2c | SNMPv3 = SNMPv3, defaultDomain: UDP_IPv4 | UDP_IPv6 = UDP_IPv4, defaultCommunity: bytes = b'public', autowait: bool = True, verboseLogging: bool = False) ### Description Instantiates an Engine object. It's recommended to only have one Engine instance. The constructor accepts keyword-only arguments for default version, domain, community, and autowait settings. The verboseLogging parameter enables detailed logging for discarded packets. ### Parameters #### Keyword Arguments - **defaultVersion** (SNMPv1 | SNMPv2c | SNMPv3) - Optional - Sets the default SNMP version. - **defaultDomain** (UDP_IPv4 | UDP_IPv6) - Optional - Sets the default transport domain. - **defaultCommunity** (bytes) - Optional - Sets the default community string. - **autowait** (bool) - Optional - Enables or disables automatic waiting for responses. - **verboseLogging** (bool) - Optional - Enables detailed logging for discarded packets. ### Usage Example ```python import logging import snmp logging.basicConfig(level=logging.DEBUG) engine = snmp.Engine(verboseLogging=True) ``` ### Notes - The `Engine` class is not thread-safe. All method calls must be done in a single thread. ``` -------------------------------- ### Add SNMP Users with Different Auth/Priv Protocols Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/engine.md Demonstrates adding users to an SNMP engine with various authentication and privacy protocols and secrets. Passwords must be bytes. The `secret` parameter can be used when auth and privacy secrets are the same. ```python from snmp import * from snmp.security.usm.auth import * from snmp.security.usm.priv import * engine = Engine() engine.addUser( "user1", authProtocol=HmacSha256, authSecret=b"auth secret", ) engine.addUser( "user2", authProtocol=HmacSha384, secret=b"auth secret", ) engine.addUser( "user3", authProtocol=HmacSha, privProtocol=AesCfb128, authSecret=b"authentication secret", privSecret=b"privacy secret", ) engine.addUser( "user4", authProtocol=HmacMd5, privProtocol=DesCbc, authSecret=b"12345", privSecret=b"12345", ) engine.addUser( "user5", authProtocol=HmacSha224, privProtocol=AesCfb128, secret=b"shared secret", ) ``` -------------------------------- ### Manager Interface - Get Request Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/library.md Sends an SNMP Get request for specified OIDs and awaits the response. The method blocks until a response is received or the timeout is reached. It returns a VarBindList on success and can raise specific exceptions for errors like NoSuchName, ErrorResponse, or Timeout. ```APIDOC ## GET get ### Description Sends an SNMP Get request and awaits the response. The positional arguments give the OIDs for the request. The method will block until a response is received, up to a maximum of timeout seconds. ### Method GET ### Endpoint manager.get(*oids: [OID](smi.md#snmp.smi.OID) | str, timeout: float = 10.0) ### Parameters #### Path Parameters - **oids** (OID | str) - Required - The Object Identifiers for the request. - **timeout** (float) - Optional - The maximum time in seconds to wait for a response. Defaults to 10.0. ### Request Example ```python vblist = manager.get("1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.3.0") # VarBindList -> VarBind -> OctetString -> bytes -> str descr = vblist[0].value.data.decode() # VarBindList -> VarBind -> TimeTicks -> int -> float uptime = vblist[1].value.value / 100 print(f"System Description: \"{descr}\"") print(f"System Up-Time: {uptime} seconds") ``` ### Response #### Success Response (200) - **VarBindList** - A list of variable bindings returned by the agent. #### Response Example ```python # Example VarBindList structure (conceptual) [ {'name': '1.3.6.1.2.1.1.1.0', 'value': 'Linux version ...'}, {'name': '1.3.6.1.2.1.1.3.0', 'value': 1234567} ] ``` ### Error Handling - **NoSuchName**: Raised when the agent cannot find the specified OID. - **ErrorResponse**: Raised for general SNMP error responses (non-zero error-status). - **Timeout**: Raised if no response is received within the specified timeout. ### Exception Example ```python oid = "1.3.6.1.2.1.1.1.0" try: vblist = manager.get(oid) except NoSuchName: print(f"This machine has no value for {oid}") except ErrorResponse as err: print(f"Error: {err.status.name}") except Timeout: print("The request timed out!") except Exception as err: print(err) ``` ``` -------------------------------- ### Get OID length Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/smi.md Returns the number of sub-identifiers in the OID. ```python __len__() ``` -------------------------------- ### Perform SNMP Get Request and Process Response Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/library.md Use this snippet to send an SNMP Get request for specified OIDs and process the returned variable bindings. It demonstrates how to decode string values and convert time ticks to seconds. Handles specific exceptions like NoSuchName, ErrorResponse, and Timeout. ```python vblist = manager.get("1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.3.0") # VarBindList -> VarBind -> OctetString -> bytes -> str descr = vblist[0].value.data.decode() # VarBindList -> VarBind -> TimeTicks -> int -> float uptime = vblist[1].value.value / 100 print(f"System Description: \"{descr}\"") print(f"System Up-Time: {uptime} seconds") ``` ```python oid = "1.3.6.1.2.1.1.1.0" try: vblist = manager.get(oid) except NoSuchName: print(f"This machine has no value for {oid}") except ErrorResponse as err: print(f"Error: {err.status.name}") except Timeout: print("The request timed out!") except Exception as err: print(err) ``` -------------------------------- ### SNMP Exception Handling Source: https://context7.com/charlestolley/python-snmp/llms.txt Demonstrates how to import and use SNMP-specific exceptions for handling various error conditions such as protocol errors, timeouts, and malformed responses. ```python from snmp import ( Engine, SNMPv1, SNMPv3, ErrorResponse, NoSuchName, Timeout, ImproperResponse, ErrorStatus, ) from snmp.security.usm.auth import HmacSha256 engine = Engine() engine.addUser("monitor", authProtocol=HmacSha256, secret=b"secret") manager_v3 = engine.Manager("192.168.1.1") manager_v1 = Engine(SNMPv1).Manager("10.0.0.99", community=b"public") ``` -------------------------------- ### Get OID sub-identifier by index or slice Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/smi.md Retrieves a single sub-identifier or a slice of sub-identifiers from the OID. ```python __getitem__(n: int | slice) ``` -------------------------------- ### addUser Method Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/engine.md Adds a user to the engine's configuration. This method is a direct reference to the Engine.addUser() method. ```APIDOC addUser(user: str, namespace: str = '', default: bool = None, authProtocol=None, privProtocol=None, authSecret: bytes = None, privSecret: bytes = None, secret: bytes = None, defaultSecurityLevel=None) ``` -------------------------------- ### Working with SNMP SMI Data Types Source: https://context7.com/charlestolley/python-snmp/llms.txt Illustrates how to construct SNMP SMI data types for SET requests and read typed values from VarBindList responses. It also shows how to handle SNMPv2 sentinel values like NoSuchObject. ```python from snmp.smi import ( Integer32, Unsigned32, Counter32, Counter64, Gauge32, TimeTicks, OctetString, IpAddress, Opaque, OID, Null, NoSuchObject, NoSuchInstance, EndOfMibView, VarBind, VarBindList, ) contact = OctetString(b"ops@example.com") # .data -> bytes ip_addr = IpAddress("192.168.1.1") # .addr -> str, .data -> bytes count = Counter32(1000000) # .value -> int ticks = TimeTicks(9550035) # .value -> int (1/100 seconds) gauge = Gauge32(512) vblist = manager.get( "1.3.6.1.2.1.1.1.0", # sysDescr -> OctetString "1.3.6.1.2.1.1.3.0", # sysUpTime -> TimeTicks "1.3.6.1.2.1.1.2.0", # sysObjectID -> OID ) descr = vblist[0].value.data.decode() uptime = vblist[1].value.value / 100 obj_id = str(vblist[2].value) print(f"descr={descr!r}, uptime={uptime}s, oid={obj_id}") for vb in vblist: if isinstance(vb.value, NoSuchObject): print(f"{vb.name}: object type unknown") elif isinstance(vb.value, NoSuchInstance): print(f"{vb.name}: no instance at this index") elif isinstance(vb.value, EndOfMibView): print(f"{vb.name}: end of MIB") else: print(f"{vb.name}: {vb.value}") ``` -------------------------------- ### Create SNMP Engine Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/getting_started.md The first step in any SNMP application is to create an Engine object. ```python from snmp import Engine engine = Engine() ``` -------------------------------- ### AsyncEngine Constructor Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/engine.md Initializes an AsyncEngine instance. Supports custom event loops and various SNMP versions and security configurations. ```APIDOC class AsyncEngine(defaultVersion: SNMPv1 | SNMPv2c | SNMPv3 = SNMPv3, defaultDomain: UDP_IPv4 | UDP_IPv6 = UDP_IPv4, defaultCommunity: bytes = b'public', verboseLogging: bool = False, loop=None) ``` -------------------------------- ### manager.get() Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/manager.md Send an SNMP Get request containing the provided list of OIDs. The method can either block until a response is received or return a RequestHandle for asynchronous processing. ```APIDOC ## get(*oids, timeout=10.0, refreshPeriod=1.0, wait=None) ### Description Send an SNMP Get request containing the provided list of OIDs. Each item in the oids argument list may be either an [`snmp.smi.OID`](smi.md#snmp.smi.OID), or a string containing the representation of the OID (e.g. `"1.3.6.1.2.1.1.1.0"`, or `".1.3.6.1.2.1.1.1.0"`). The default behavior (asterisk) for this method is to block until a response is received, and then return the contents of the response in a [`VarBindList`](smi.md#snmp.smi.VarBindList). However, when called with `wait=False`, it will not wait for a response, and instead return a `RequestHandle` corresponding to the request. You can then call the `RequestHandle.wait()` method to await the response and retrieve its contents. ### Parameters #### Path Parameters - **oids** (OID or str) - Required - A list of OIDs to request. - **timeout** (float) - Optional - The maximum time in seconds to wait for a response before timing out. Defaults to 10.0 seconds. - **refreshPeriod** (float) - Optional - The interval in seconds between re-sending the request if no response is received. Defaults to 1.0 second. - **wait** (bool or None) - Optional - If True, block until a response is received. If False, return a `RequestHandle` immediately. If None, the behavior is determined by the `autowait` parameter of the `Engine` or `Manager` constructor. ### Request Example ```python # Blocking call vblist = manager.get("1.3.6.1.2.1.1.1.0", wait=True) # Non-blocking call, then wait for response handle = manager.get("1.3.6.1.2.1.1.1.0", wait=False) vblist = handle.wait() # Parallel requests handle1 = manager1.get("1.3.6.1.2.1.1.1.0", wait=False) handle2 = manager2.get("1.3.6.1.2.1.1.1.0", wait=False) vblist1 = handle1.wait() vblist2 = handle2.wait() ``` ### Response #### Success Response (VarBindList) - **VarBindList** - A list of variable bindings representing the SNMP response. #### Error Response - **snmp.Timeout** - Raised if no response is received within the specified `timeout`. - **snmp.ErrorResponse** - Raised for any other SNMP error response. - **snmp.NoSuchName** - A specific type of `snmp.ErrorResponse` for the `noSuchName` error status. ``` -------------------------------- ### Engine.Manager - Creating a Manager Object Source: https://context7.com/charlestolley/python-snmp/llms.txt Explains how to create a `Manager` object using the `Engine.Manager` factory method. This object is pre-configured for a specific remote SNMP agent and supports different SNMP versions. ```APIDOC ## Engine.Manager — creating a Manager object Factory method that returns a version-appropriate Manager object (`SNMPv3Manager`, `SNMPv2cManager`, or `SNMPv1Manager`) pre-configured for a single remote SNMP agent. Accepts address as a string or `(host, port)` tuple; default port is `161`. ```python from snmp import Engine, SNMPv1, SNMPv2c, SNMPv3, UDP_IPv6 engine = Engine() engine.addUser("admin", authProtocol=..., secret=b"secret") # SNMPv3 manager (default version) router = engine.Manager("192.168.1.1") ``` ``` -------------------------------- ### Send SNMP GetNext Request Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/manager.md Use getNext to send an SNMP GetNext request. Its usage and behavior are identical to the get() method, but it retrieves the next OID in the MIB tree. ```python pass # Example usage would be similar to get() ``` -------------------------------- ### Add User with Authentication and Privacy Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/getting_started.md Configure user credentials for authentication and privacy protocols. The secret parameter is used when authSecret and privSecret are the same. Passwords must be bytes. ```python from snmp import Engine from snmp.security.usm.auth import HmacSha256 from snmp.security.usm.priv import AesCfb128 engine.addUser( "admin", authProtocol=HmacSha256, privProtocol=AesCfb128, secret=b"maplesyrup", ) ``` -------------------------------- ### Engine.addUser - Configuring SNMPv3 Credentials Source: https://context7.com/charlestolley/python-snmp/llms.txt Details on how to register authentication and privacy algorithms and secrets for SNMPv3 users using the `addUser` method on the `Engine` object. It covers various configurations including separate or shared secrets and different security levels. ```APIDOC ## Engine.addUser — configuring SNMPv3 credentials Registers authentication and privacy algorithms and secrets for a named SNMPv3 user. Supports separate auth/priv secrets or a single shared secret. The first user added automatically becomes the default; subsequent calls can override this with `default=True`. ```python from snmp import Engine from snmp.security.usm.auth import HmacMd5, HmacSha, HmacSha224, HmacSha256, HmacSha384, HmacSha512 from snmp.security.usm.priv import AesCfb128, DesCbc engine = Engine() # Auth only, separate secret engine.addUser("user1", authProtocol=HmacSha256, authSecret=b"auth secret") # Auth only, shared secret shorthand engine.addUser("user2", authProtocol=HmacSha384, secret=b"auth secret") # Auth + priv, separate secrets engine.addUser( "user3", authProtocol=HmacSha, privProtocol=AesCfb128, authSecret=b"authentication secret", privSecret=b"privacy secret", ) # Auth + priv, shared secret — engine picks highest available security level engine.addUser( "user5", authProtocol=HmacSha224, privProtocol=AesCfb128, secret=b"shared secret", default=True, # make this the default user for new Managers ) # Override default security level downward engine.addUser( "user6", authProtocol=HmacSha512, privProtocol=AesCfb128, secret=b"secret", defaultSecurityLevel=snmp.authNoPriv, # force authNoPriv even though priv is configured ) ``` ``` -------------------------------- ### Manager Interface - GetBulk Request Source: https://github.com/charlestolley/python-snmp/blob/develop/docs/source/library.md Sends an SNMP GetBulk request and awaits the response. This method supports the `nonRepeaters` and `maxRepetitions` parameters, in addition to the standard parameters of the `get()` method. ```APIDOC ## GET getBulk ### Description Send an SNMP GetBulk request and await the response. The behavior of this method is the same as the `get()` method, aside from the request type, and the addition of the nonRepeaters and maxRepetitions parameters. ### Method GET ### Endpoint manager.getBulk(*oids: [OID](smi.md#snmp.smi.OID) | str, nonRepeaters: int = 0, maxRepetitions: int = 1, timeout: float = 10.0) ### Parameters #### Path Parameters - **oids** (OID | str) - Required - The Object Identifiers for the request. - **nonRepeaters** (int) - Optional - The number of OIDs that are not repeated. Defaults to 0. - **maxRepetitions** (int) - Optional - The maximum number of repetitions for each non-repeating OID. Defaults to 1. - **timeout** (float) - Optional - The maximum time in seconds to wait for a response. Defaults to 10.0. ### Request Example ```python # Example usage for getBulk bulk_data = manager.getBulk("1.3.6.1.2.1.1.1.0", nonRepeaters=1, maxRepetitions=5) ``` ### Response #### Success Response (200) - **VarBindList** - A list of variable bindings returned by the agent. ### Error Handling - **NoSuchName**: Raised when the agent cannot find the specified OID. - **ErrorResponse**: Raised for general SNMP error responses (non-zero error-status). - **Timeout**: Raised if no response is received within the specified timeout. ```