Poll SNMP with Python (pysnmp)
You've got a server exporting metrics over SNMP, and you'd rather pull them into your own Python code than bolt on a heavyweight monitoring stack. That's where pysnmp comes in — a pure-Python SNMP engine that lets a script speak the protocol directly, with no C library underneath. This guide walks through python snmp polling from the ground up: which OIDs are worth grabbing, how to fetch them, where pysnmp earns its keep and where the plain Net-SNMP command line is honestly faster, and the one blind spot every on-host poller shares. Real OIDs. Runnable commands. No hand-waving.
The problem you're actually trying to solve
Picture the setup. You have a handful of Linux boxes — web nodes, a database, maybe a VPS or two — and each already runs an SNMP agent that publishes CPU, memory, disk, and interface counters. You don't want a full observability platform. You want a Python script. Something you can drop into a cron job, a data pipeline, or a Flask endpoint, that reads a couple of numbers and does something useful with them.
SNMP is the right wire protocol for that job. Your servers and switches already speak it, so you skip installing per-metric exporters. The catch is the protocol itself. Underneath the friendly OID strings sits ASN.1, BER encoding, versioned protocol operations, community strings, and a management information tree that reads like a phone book. Nobody wants to hand-roll that. So the real question isn't "can Python read SNMP" — it obviously can — but "what's the least fragile way to do it," and that's the decision this page is about.

How pysnmp fits alongside the alternatives
There are two honest paths, and picking the right one saves you a weekend.
The first is a native Python library. pysnmp is the best-known — a from-scratch implementation of the SNMP engine in pure Python, so your code builds and sends requests without shelling out to anything. It handles v1, v2c, and v3, and it keeps everything inside the interpreter, which is lovely when you're already deep in an async application or you need SNMPv3's authentication and encryption woven into Python logic.
The second path is deceptively boring: call the Net-SNMP command-line tools from Python. snmpget and snmpwalk are rock-solid, battle-tested C binaries. Wrap them in subprocess, parse the text they print, done. For a script that reads a few OIDs on a timer, this is often the pragmatic winner — fewer moving parts, and the exact same commands you'd type by hand.
- Reach for pysnmp when you want a self-contained Python dependency, async polling of many hosts, or SNMPv3 handled inside your app.
- Reach for the CLI wrapper when Net-SNMP is already installed, you value stability over elegance, or you're prototyping and want something running in five minutes.
| Factor | pysnmp (native) | Net-SNMP CLI wrapper |
|---|---|---|
| Dependency | Pure Python, no C libs | Needs Net-SNMP installed |
| SNMP versions | v1, v2c, v3 | v1, v2c, v3 |
| Best fit | Async apps, in-code SNMPv3 | Cron jobs, quick prototypes |
| Debugging | Inside Python | Reproduce in a shell |
Whichever you choose, the OIDs and the semantics are identical. The library is just plumbing.
Step-by-step: python snmp polling end to end
Here's the whole loop, from a server that answers to a number in your script.
- Confirm the agent responds. Before Python touches anything, prove the target is reachable with the reference tools. If this fails, no library will save you:
That walkssnmpwalk -v2c -c public 10.0.0.5 1.3.6.1.2.1.25.3.3.1.2hrProcessorLoad— per-core CPU load, one row per logical processor. See SNMP CPU monitoring for what the value means. - Pick your OIDs. Decide what you're charting. CPU lives at
1.3.6.1.2.1.25.3.3.1.2; the wider sensor & OID catalog lists memory, storage, uptime, and interface counters. Write the numeric OIDs down — your script shouldn't depend on MIB files being installed locally. - Choose the transport. For read-only polling on a trusted segment, SNMPv2c with a read-only community string is standard. If the data crosses untrusted links, step up to SNMPv3.
- Fetch in Python. Either build the request with pysnmp, or invoke
snmpget/snmpwalkthroughsubprocessand read stdout. - Parse the value. SNMP returns typed data — an
INTEGERfor CPU load,Counter32/Counter64for interface octets,TimeTicksfor uptime. Cast it to the Python type you need and keep the OID index if you walked a table. - Store or act. Push the number into a time-series database, a Grafana source, or a threshold check. If it's for dashboards, Grafana with SNMP picks up where this leaves off.
- Loop on a cadence. Poll on a fixed interval — every minute or five — and, critically, evaluate trends across samples rather than reacting to one lonely reading.
Two gotchas trip people up. An empty walk almost always means the OID isn't in the agent's OID allowlist, not that your code is broken. And counter values like interface octets are cumulative — you subtract consecutive samples and divide by the elapsed seconds to get a rate. Miss that and your "traffic" graph is nonsense.
A working configuration example
The most portable pattern wraps the reference CLI. It's honest about what it does and easy to debug — if the Python misbehaves, you run the same command in a terminal and compare.
import subprocess
def snmp_get(host, community, oid, port=161):
# Calls Net-SNMP's snmpget and returns the raw value string.
cmd = [
"snmpget", "-v2c", "-c", community,
"-Ovq", # value only, no type prefix
f"{host}:{port}", oid,
]
out = subprocess.run(cmd, capture_output=True, text=True, check=True)
return out.stdout.strip()
# Read core 0's load (hrProcessorLoad, index 196608):
cpu = snmp_get("10.0.0.5", "public", "1.3.6.1.2.1.25.3.3.1.2.196608")
print(int(cpu)) # -> e.g. 7 (percent, 0-100)
The -Ovq flags tell Net-SNMP to print the bare value, so int() just works. Swap in pysnmp later if you outgrow this — the OID and the meaning don't change, only the transport. On the server side, whatever you poll must be published; the snmpd.conf guide shows the read-only v2c config and the view lines that expose each OID. Keep the community string out of your source and read it from an environment variable or secret store — it travels in clear text on v2c, so treat it as a password.
Alerting from outside the box
Here's the blind spot I promised. A Python poller running on the same server it watches can only report while that server is healthy enough to run Python. Peg the CPU, exhaust memory, or crash the box, and your script goes down with the ship — right at the moment you most needed a page. Local monitoring answers "is this metric high?" but it cannot answer "is this machine still alive?" from a position of safety.
The fix is to poll from somewhere else. That's the whole premise of double durability: an independent watcher, off the host, keeps reading your OIDs even when the server has gone dark. SNMP is a pull protocol, so an external checker just queries the same numbers — CPU, disk, uptime — on its own hardware and alerts on its own schedule. The sick server doesn't have to cooperate.
You can stand that up yourself, or hand it off. ostr.io Monitoring polls your SNMP endpoint from outside your network and fires real-time email and SMS alerts when a reading crosses your limit — so an overloaded box still reaches you, even when it can't run your Python at all.
