Windows + Python3でSNMPを扱おうとしたところ、PySNMPが動きそうでした。
そこで、公式ドキュメントや書籍を見て手を動かした時のメモを残します。
なお、SNMPデータの取得元として、今回は昔使ったプリンタPX-105のインク本数を取得してみました。
Ruby + Sinatra + SNMPでPX-105のインク残量を取得・表示する - メモ的な思考的な
環境
- Windows10 x64
- Python 3.5.1 32bit
- PySNMP 4.3.2
なお、PySNMPはPyCryptoに依存しています。
そのため、WindowsのPython3.5の環境にインストールするにはVisual Studio 2015、または、Visual C++ Build Tools 2015
を事前にインストールしておきます。
Pythonの拡張モジュールインストール時にvcvarsall.batエラーが出たため、Visual C++ Build Tools 2015でビルドした - メモ的な思考的な
D:\Sandbox\pysnmp_sample>virtualenv -p c:\python35-32\python.exe env D:\Sandbox\pysnmp_sample>env\Scripts\activate (env) D:\Sandbox\pysnmp_sample>pip install pysnmp (env) D:\Sandbox\pysnmp_sample>pip list pip (8.1.2) ply (3.8) pyasn1 (0.1.9) pycrypto (2.6.1) pysmi (0.0.7) pysnmp (4.3.2) setuptools (22.0.5) wheel (0.29.0)
GET requestの送信
PySNMPのドキュメントを読んだところ、実装方法として、
の2つがありました。
どちらを試そうかと考えましたが、ドキュメントには
Unless you have a vary specific task, one of high-level APIs might solve your SNMP needs.
と書かれていたため、今回はHigh-level SNMP
だけ試してみます。
ドキュメントによると、基本的な流れは、
pysnmp.hlapi.getCmd()
でコマンドを作成- 作ったコマンドを
next()
で実行
のようでした。
pysnmp.hlapi.getCmd()
ではいくつか引数がありました。
GET command — PySNMP
今回設定した内容は
authData
には、pysnmp.hlapi.CommunityData
を使って、コミュニティ名とSNMPのバージョンを指定- デフォルトの場合、SNMPのバージョンは
SNMPv2c
となることに注意
- デフォルトの場合、SNMPのバージョンは
transportTarget
には、pysnmp.hlapi.UdpTransportTarget
を使って、ターゲットのIPアドレスとUDPポートを指定*varBinds
には、OIDの値をセット
でした。
実装と実行結果は以下の通りです。
import pysnmp.hlapi OID_MARKER_PROCESS_COLORANTS = "1.3.6.1.2.1.43.10.2.1.6.1.1" g = pysnmp.hlapi.getCmd( pysnmp.hlapi.SnmpEngine(), pysnmp.hlapi.CommunityData(SNMP_COMMUNITY, mpModel=0), pysnmp.hlapi.UdpTransportTarget((IP, PORT)), pysnmp.hlapi.ContextData(), pysnmp.hlapi.ObjectType(pysnmp.hlapi.ObjectIdentity(OID_MARKER_PROCESS_COLORANTS)) ) errIndication, errorStatus, errorIndex, varBinds = next(g) print(varBinds) # => [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.43.10.2.1.6.1.1')), Integer32(4))]
また、ドキュメントには書かれていないものの、この本に書かれていたものも試してみます。
Pro Python System Administration - Apress IT eBooks & Books
from pysnmp.entity.rfc3413.oneliner import cmdgen OID_MARKER_PROCESS_COLORANTS = "1.3.6.1.2.1.43.10.2.1.6.1.1" cg = cmdgen.CommandGenerator() errIndication, errorStatus, errorIndex, varBinds = cg.getCmd( cmdgen.CommunityData('my-manager', SNMP_COMMUNITY, mpModel=0), cmdgen.UdpTransportTarget((IP, PORT)), OID_MARKER_PROCESS_COLORANTS ) print(varBinds) # => [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.43.10.2.1.6.1.1')), Integer32(4))]
同じように動作しました。
前者と後者、どちらを使うのが良いのか分からなかったため、PySNMPのソースコードを読んでみました。ただ、いくつも同じようなファイルやソースコードが並んでいて読み解くのが難しかったこともあり、諦めました。
ドキュメントに記載されている分、前者のほうが良いのでしょうか。
ソースコード
GitHubに上げました。
thinkAmi-sandbox/PySNMP-sample
Windowsでは扱えないもの
PySNMP以外にもPythonライブラリはありましたが、いずれもWindowsで使うのは難しそうでした。
Snimpy
SNMPを扱うためにPySNMPを使っているものの、PyPIにOSとしてPOSIXが必要そうだったため、諦めました。
- Snimpy: SNMP & Python | Vincent Bernat
- Snimpy: interactive SNMP tool — Snimpy 0.8.10.post5 documentation
- vincentbernat/snimpy: interactive SNMP tool with Python