<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sumit Dhaka</title>
    <description>The latest articles on Forem by Sumit Dhaka (@tosumitdhaka).</description>
    <link>https://forem.com/tosumitdhaka</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3763376%2Fe5732a10-8442-4a4d-bbb4-176b093db048.jpg</url>
      <title>Forem: Sumit Dhaka</title>
      <link>https://forem.com/tosumitdhaka</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tosumitdhaka"/>
    <language>en</language>
    <item>
      <title>Trishul SNMP Suite 2.0.1: Better MIBs, Traps, and SNMP Labs</title>
      <dc:creator>Sumit Dhaka</dc:creator>
      <pubDate>Mon, 25 May 2026 16:57:17 +0000</pubDate>
      <link>https://forem.com/tosumitdhaka/trishul-snmp-suite-201-better-mibs-traps-and-snmp-labs-196f</link>
      <guid>https://forem.com/tosumitdhaka/trishul-snmp-suite-201-better-mibs-traps-and-snmp-labs-196f</guid>
      <description>&lt;p&gt;Trishul SNMP Suite is an SNMP lab and operations shell for people who need to simulate devices, walk targets, send and receive traps, browse MIB trees, and manage real vendor MIB corpora from one place.&lt;/p&gt;

&lt;p&gt;If you are new to the project, that is the short intro.&lt;/p&gt;

&lt;p&gt;If you last saw it around &lt;code&gt;1.2.5&lt;/code&gt;, &lt;code&gt;2.0.1&lt;/code&gt; is the point where the project stops feeling like “a useful UI with a lot of features” and starts feeling like a cleaner platform with a much stronger core.&lt;/p&gt;

&lt;p&gt;That is the real story of this release.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/tosumitdhaka/trishul-snmp-suite" rel="noopener noreferrer"&gt;github.com/tosumitdhaka/trishul-snmp-suite&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzyhkc0cx33ugyrpvq7p2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzyhkc0cx33ugyrpvq7p2.png" alt="Trishul SNMP Suite 2.0.1 demo" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get today
&lt;/h2&gt;

&lt;p&gt;Compared with the &lt;code&gt;1.2.x&lt;/code&gt; era, Trishul SNMP Suite now gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one FastAPI application serving the UI, API, and WebSocket layer&lt;/li&gt;
&lt;li&gt;one in-process SNMP runtime powered by the in-house &lt;code&gt;trishul-snmp&lt;/code&gt; library&lt;/li&gt;
&lt;li&gt;one bundle-first MIB compilation pipeline powered by the in-house &lt;code&gt;trishul-smi&lt;/code&gt; library&lt;/li&gt;
&lt;li&gt;SQLite-backed durable state for sessions, settings, bundles, and notification history&lt;/li&gt;
&lt;li&gt;one unified &lt;code&gt;/api/...&lt;/code&gt; surface instead of split route families&lt;/li&gt;
&lt;li&gt;a cleaner single-container deployment path&lt;/li&gt;
&lt;li&gt;better MIB inventory handling, smarter exports, richer trap workflows, and a more intuitive browser experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pages are still familiar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Dashboard&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Simulator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Walk &amp;amp; Parse&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Traps&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MIB Browser&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MIB Manager&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Settings&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the system underneath those pages is much more coherent now.&lt;/p&gt;

&lt;h2&gt;
  
  
  From 1.2.x to 2.0.1, in one view
&lt;/h2&gt;

&lt;p&gt;I do not want to turn this into a changelog dump, so here is the short version of the journey:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1.2.x&lt;/code&gt; established the operator experience: MIB Browser, realtime dashboard behavior, simulator improvements, trap workflows, drag-and-drop MIB upload, auto-validation, and a more usable UI&lt;/li&gt;
&lt;li&gt;later &lt;code&gt;1.x&lt;/code&gt; releases hardened the product with better security, better tests, better docs, better deployment, and a single-suite packaging path&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2.0.0&lt;/code&gt; rebuilt the core runtime and MIB pipeline around a much cleaner architecture&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2.0.1&lt;/code&gt; is the release where that architecture starts paying off in the workflows users touch every day&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the headline is not just “more features since &lt;code&gt;1.2.5&lt;/code&gt;.”&lt;/p&gt;

&lt;p&gt;The headline is that the same kind of workflows now run on a much better foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built &lt;code&gt;trishul-smi&lt;/code&gt; and &lt;code&gt;trishul-snmp&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This is the part I most wanted to share.&lt;/p&gt;

&lt;p&gt;As the project grew, two kinds of friction kept showing up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;MIB compilation and compiled-data usage were too important to remain a loosely connected side concern.&lt;/li&gt;
&lt;li&gt;SNMP runtime behavior was too central to keep treating it like a set of worker-style runtime pieces that had to be coordinated from the outside.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wanted the product to have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a first-class compiled MIB artifact&lt;/li&gt;
&lt;li&gt;a shared in-memory representation that browser, catalog, trap enrichment, and runtime features could all rely on&lt;/li&gt;
&lt;li&gt;runtime control that lived inside the application instead of being orchestrated through extra process boundaries&lt;/li&gt;
&lt;li&gt;cleaner APIs for the exact behavior the product needed&lt;/li&gt;
&lt;li&gt;simpler debugging and testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why I moved core responsibilities into two in-house libraries.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;trishul-smi&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;trishul-smi&lt;/code&gt; is the MIB compilation side of the platform.&lt;/p&gt;

&lt;p&gt;Instead of compiling MIBs and then treating the output as a loose set of files, the app now works with a bundle-first model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;versioned bundle storage&lt;/li&gt;
&lt;li&gt;compile metadata&lt;/li&gt;
&lt;li&gt;activation state&lt;/li&gt;
&lt;li&gt;compile history&lt;/li&gt;
&lt;li&gt;one active compiled bundle loaded for queries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gives Trishul a more reliable answer to questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which modules are active right now?&lt;/li&gt;
&lt;li&gt;which modules belong to which source group?&lt;/li&gt;
&lt;li&gt;which module is shadowed and why?&lt;/li&gt;
&lt;li&gt;what should the browser, trap catalog, and runtime resolve against?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;trishul-snmp&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;trishul-snmp&lt;/code&gt; is the runtime side of the platform.&lt;/p&gt;

&lt;p&gt;It lets the suite run the responder, manager-side operations, notification listener, trap and inform sending, and bundle-backed symbolic behavior inside the app itself.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no subprocess choreography as the main runtime model&lt;/li&gt;
&lt;li&gt;no shell-outs as the normal SNMP execution path&lt;/li&gt;
&lt;li&gt;no extra worker coordination just to keep trap, stats, and simulator state aligned&lt;/li&gt;
&lt;li&gt;fewer layers between the UI, state, and runtime behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was not “let’s build in-house libraries for the sake of it.”&lt;/p&gt;

&lt;p&gt;It was a practical decision: the product had reached a point where better internal control over the MIB pipeline and SNMP runtime would improve both developer velocity and operator experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the architecture looks like now
&lt;/h2&gt;

&lt;p&gt;A comparison table explains the shift better than a diagram:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;Earlier line&lt;/th&gt;
&lt;th&gt;2.0.1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MIB compilation&lt;/td&gt;
&lt;td&gt;pysmi-style compilation and looser generated artifacts around the app.&lt;/td&gt;
&lt;td&gt;trishul-smi drives a bundle-first pipeline with versioned bundles, activation, source attribution, and export-friendly metadata.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Catalog query source&lt;/td&gt;
&lt;td&gt;Browser and catalog views leaned on generated artifacts and pysnmp mibBuilder-style runtime views.&lt;/td&gt;
&lt;td&gt;The active in-memory bundle is the source of truth for browser, catalog, exports, and resolution.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SNMP runtime&lt;/td&gt;
&lt;td&gt;Subprocess-based pysnmp workers, with separate simulator and trap receiver processes and UDP loopback coordination.&lt;/td&gt;
&lt;td&gt;trishul-snmp runs responder, manager operations, trap send and receive, and symbolic behavior in-process.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App topology&lt;/td&gt;
&lt;td&gt;More glue between runtime pieces, route families, and cross-process status updates.&lt;/td&gt;
&lt;td&gt;One FastAPI application serves the UI, API, and WebSocket layer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State and stats&lt;/td&gt;
&lt;td&gt;More file-backed and process-coordination-heavy runtime state, including file-based stats flow.&lt;/td&gt;
&lt;td&gt;SQLite-backed state now covers settings, sessions, bundles, notification history, and persisted counters.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;More moving pieces to explain and reason about.&lt;/td&gt;
&lt;td&gt;One suite, one app surface, one cleaner container path.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That simplicity matters.&lt;/p&gt;

&lt;p&gt;It reduces the amount of glue code needed to keep everything coherent, and it makes features easier to add without creating a larger mess around them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What users will notice first
&lt;/h2&gt;

&lt;p&gt;All of that architecture work would not matter much if the workflows still felt awkward.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;2.0.1&lt;/code&gt;, they do not.&lt;/p&gt;

&lt;h3&gt;
  
  
  More trustworthy compiled MIB data
&lt;/h3&gt;

&lt;p&gt;This is one of the biggest practical improvements in the product.&lt;/p&gt;

&lt;p&gt;Trishul now handles compiled MIB data with much clearer source attribution and bundle semantics. It distinguishes the deduplicated active runtime view from the per-source-group inventory view. That becomes very important once you load overlapping vendor corpora or want bundle-specific exports instead of a blurred “everything together” view.&lt;/p&gt;

&lt;p&gt;The result is a more trustworthy MIB model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;better duplicate and shadowed-module handling&lt;/li&gt;
&lt;li&gt;clearer active-versus-source inventory behavior&lt;/li&gt;
&lt;li&gt;better failed-module reporting&lt;/li&gt;
&lt;li&gt;more reliable compiled data for exports and downstream workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the kind of improvement that makes operators trust what the app is showing them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better trap workflows
&lt;/h3&gt;

&lt;p&gt;Trap handling is also much better in day-to-day use.&lt;/p&gt;

&lt;p&gt;The trap flow now supports richer varbind editing, including enum-aware varbind dropdown behavior that makes common notification work more natural. Trap history is also more coherent because stored events preserve the event-time view of resolution data instead of drifting with whatever the current toggle state happens to be.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;better trap varbind authoring&lt;/li&gt;
&lt;li&gt;clearer trap history behavior&lt;/li&gt;
&lt;li&gt;stronger confidence in what a stored trap event actually represents&lt;/li&gt;
&lt;li&gt;better live operator experience around traps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For SNMP tooling, this matters a lot. Trap workflows become frustrating fast when the tool is “almost right.”&lt;/p&gt;

&lt;h3&gt;
  
  
  A smarter MIB Browser
&lt;/h3&gt;

&lt;p&gt;The MIB Browser was already one of the most visible features in the older line. In &lt;code&gt;2.0.1&lt;/code&gt;, it feels much more intentional.&lt;/p&gt;

&lt;p&gt;Search and type filtering work together more naturally. Filtered trees can auto-expand so users can actually see the result immediately. Interaction is also less fussy: larger click targets and smaller browser UX refinements make the tree feel more responsive and less fragile.&lt;/p&gt;

&lt;p&gt;That turns into better everyday behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;faster drill-down&lt;/li&gt;
&lt;li&gt;less hunting through collapsed branches&lt;/li&gt;
&lt;li&gt;more intuitive expand and collapse interaction&lt;/li&gt;
&lt;li&gt;fewer dead-click moments in the tree&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is exactly the kind of improvement users notice even if they do not name it explicitly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better exports and catalog behavior
&lt;/h3&gt;

&lt;p&gt;Exports are now much more aligned with what the user actually selected.&lt;/p&gt;

&lt;p&gt;Source-group-scoped exports respect source-group membership instead of collapsing everything into the currently active deduplicated view. Export filenames are more useful. Stats export is also cleaner and does not drag the full runtime OID catalog into every export by default.&lt;/p&gt;

&lt;p&gt;That makes exported data feel like a real operational artifact rather than a generic dump.&lt;/p&gt;

&lt;h3&gt;
  
  
  More stable page-to-page behavior
&lt;/h3&gt;

&lt;p&gt;One quiet but important improvement in the &lt;code&gt;2.0.x&lt;/code&gt; line is that the app relies less on expensive reprocessing when users switch pages.&lt;/p&gt;

&lt;p&gt;Because the platform now has clearer persisted state and runtime ownership, dashboard counters, MIB views, and related status panels behave more predictably when moving between screens.&lt;/p&gt;

&lt;p&gt;That translates into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;less waiting&lt;/li&gt;
&lt;li&gt;fewer stuck loading states&lt;/li&gt;
&lt;li&gt;less repeated inventory work&lt;/li&gt;
&lt;li&gt;better confidence that the UI reflects the current runtime state&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Many smaller UI and UX refinements matter too
&lt;/h2&gt;

&lt;p&gt;Not everything valuable belongs in a release headline.&lt;/p&gt;

&lt;p&gt;Some of the improvements in &lt;code&gt;2.0.1&lt;/code&gt; are small on paper but meaningful in daily use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;broader click targets in browser trees&lt;/li&gt;
&lt;li&gt;more intuitive expand and collapse behavior&lt;/li&gt;
&lt;li&gt;better filtered auto-expansion&lt;/li&gt;
&lt;li&gt;cleaner loading and status feedback&lt;/li&gt;
&lt;li&gt;less friction in modal-driven flows&lt;/li&gt;
&lt;li&gt;more consistent page-to-page behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the kinds of changes that make the product feel sharper even when users cannot point to a single “killer feature.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this helps developers too
&lt;/h2&gt;

&lt;p&gt;One of the easiest ways to slow down a tooling project is to keep layering features on top of an architecture that is getting harder and harder to reason about.&lt;/p&gt;

&lt;p&gt;Eventually you pay for that in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;state bugs&lt;/li&gt;
&lt;li&gt;UI inconsistencies&lt;/li&gt;
&lt;li&gt;release risk&lt;/li&gt;
&lt;li&gt;painful debugging&lt;/li&gt;
&lt;li&gt;slower feature delivery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Moving the platform toward &lt;code&gt;trishul-smi&lt;/code&gt; and &lt;code&gt;trishul-snmp&lt;/code&gt; changed that for Trishul SNMP Suite.&lt;/p&gt;

&lt;p&gt;For developers, the benefits are direct:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fewer layers to mentally unpack&lt;/li&gt;
&lt;li&gt;flatter service architecture&lt;/li&gt;
&lt;li&gt;clearer boundaries between compile, runtime, and UI concerns&lt;/li&gt;
&lt;li&gt;stronger testability&lt;/li&gt;
&lt;li&gt;better release validation and observability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For users, the same architecture work shows up as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;better reliability&lt;/li&gt;
&lt;li&gt;more predictable workflows&lt;/li&gt;
&lt;li&gt;cleaner logs&lt;/li&gt;
&lt;li&gt;easier deployment&lt;/li&gt;
&lt;li&gt;more trustworthy data in the UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the kind of internal rewrite I like: one that results in visible product quality, not just prettier internal diagrams.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few snips
&lt;/h2&gt;

&lt;h3&gt;
  
  
  One-shot install
&lt;/h3&gt;

&lt;p&gt;If you just want to try the released suite on a Docker host, this is the quickest path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-LfsS&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; install-trishul-snmp-suite.sh &lt;span class="se"&gt;\&lt;/span&gt;
  https://raw.githubusercontent.com/tosumitdhaka/trishul-snmp-suite/v2.0.1/install-trishul-snmp-suite.sh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; bash install-trishul-snmp-suite.sh up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Default access after startup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI: &lt;code&gt;http://localhost:8980&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;API docs: &lt;code&gt;http://localhost:8980/docs&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;default login: &lt;code&gt;admin / admin123&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Unified API shape
&lt;/h3&gt;

&lt;p&gt;One part I like in the current release is that the API shape is much easier to explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/meta
/api/health
/api/ws
/api/settings/*
/api/stats/*
/api/simulator/*
/api/walk/*
/api/traps/*
/api/mibs/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is a small thing, but it makes the product easier to understand for both developers and operators.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trap send example
&lt;/h3&gt;

&lt;p&gt;The current trap flow is also easier to demonstrate with one clean request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1162&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"community"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"oid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IF-MIB::linkDown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"varbinds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"oid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.3.6.1.2.1.2.2.1.1.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Integer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That kind of simple, direct workflow is exactly what I wanted the platform to support better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why &lt;code&gt;2.0.1&lt;/code&gt; matters
&lt;/h2&gt;

&lt;p&gt;I do not think &lt;code&gt;2.0.1&lt;/code&gt; should be read as “just the next point release.”&lt;/p&gt;

&lt;p&gt;&lt;code&gt;2.0.0&lt;/code&gt; did the heavy architectural lift. &lt;code&gt;2.0.1&lt;/code&gt; is where the system starts feeling polished enough that the benefits are obvious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more reliable compiled data&lt;/li&gt;
&lt;li&gt;better source-aware inventory and exports&lt;/li&gt;
&lt;li&gt;richer trap authoring&lt;/li&gt;
&lt;li&gt;smarter browsing&lt;/li&gt;
&lt;li&gt;quieter and more useful logs&lt;/li&gt;
&lt;li&gt;cleaner install and runtime defaults&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That combination is what makes the release interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;If you are new to Trishul SNMP Suite, &lt;code&gt;2.0.1&lt;/code&gt; is a good point to try it because the platform is now much easier to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one app&lt;/li&gt;
&lt;li&gt;one runtime&lt;/li&gt;
&lt;li&gt;one MIB pipeline&lt;/li&gt;
&lt;li&gt;one installer path&lt;/li&gt;
&lt;li&gt;familiar operator pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you knew the older &lt;code&gt;1.2.x&lt;/code&gt; line, &lt;code&gt;2.0.1&lt;/code&gt; is where the project starts paying off the deeper work behind the scenes.&lt;/p&gt;

&lt;p&gt;The UI is better. The MIB data is more trustworthy. Trap workflows are better. The browser is more intuitive. The deployment story is simpler. And the in-house &lt;code&gt;trishul-smi&lt;/code&gt; and &lt;code&gt;trishul-snmp&lt;/code&gt; foundation gives the project a much stronger path forward.&lt;/p&gt;

&lt;p&gt;That is the release I wanted to ship.&lt;/p&gt;

&lt;p&gt;If you work with SNMP labs, MIB-heavy device testing, or trap-driven workflows, I would love to know what you would want to see next: deeper bundle controls, richer browser/catalog features, stronger simulator behavior, or more advanced trap tooling.&lt;/p&gt;

</description>
      <category>snmp</category>
      <category>python</category>
      <category>fastapi</category>
      <category>opensource</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Sumit Dhaka</dc:creator>
      <pubDate>Sun, 22 Feb 2026 13:02:51 +0000</pubDate>
      <link>https://forem.com/tosumitdhaka/-3dl</link>
      <guid>https://forem.com/tosumitdhaka/-3dl</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-now-with-real-time-websocket-push-3782" class="crayons-story__hidden-navigation-link"&gt;I Built a Free, Self-Hosted SNMP Toolkit — Now With Real-Time WebSocket Push&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/tosumitdhaka" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3763376%2Fe5732a10-8442-4a4d-bbb4-176b093db048.jpg" alt="tosumitdhaka profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/tosumitdhaka" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Sumit Dhaka
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Sumit Dhaka
                
              
              &lt;div id="story-author-preview-content-3275102" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/tosumitdhaka" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3763376%2Fe5732a10-8442-4a4d-bbb4-176b093db048.jpg" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Sumit Dhaka&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-now-with-real-time-websocket-push-3782" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 22&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-now-with-real-time-websocket-push-3782" id="article-link-3275102"&gt;
          I Built a Free, Self-Hosted SNMP Toolkit — Now With Real-Time WebSocket Push
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/networking"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;networking&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-now-with-real-time-websocket-push-3782" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-now-with-real-time-websocket-push-3782#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>networking</category>
      <category>python</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built a Free, Self-Hosted SNMP Toolkit — Now With Real-Time WebSocket Push</title>
      <dc:creator>Sumit Dhaka</dc:creator>
      <pubDate>Sun, 22 Feb 2026 13:01:01 +0000</pubDate>
      <link>https://forem.com/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-now-with-real-time-websocket-push-3782</link>
      <guid>https://forem.com/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-now-with-real-time-websocket-push-3782</guid>
      <description>&lt;p&gt;If you've ever worked with SNMP — testing NMS integrations, debugging trap handlers, or validating MIB structures — you know the pain. You end up juggling Net-SNMP CLI commands you can never remember, &lt;code&gt;snmptrapd&lt;/code&gt; configs scattered everywhere, and a $500 MIB browser that still looks like it was designed in 2003.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;Trishul SNMP Suite&lt;/strong&gt; to fix that. One Docker container. Browser-based. Free.&lt;/p&gt;

&lt;p&gt;This post covers what's new in &lt;strong&gt;v1.2.4&lt;/strong&gt; — the biggest update yet — and why I built it this way.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is Trishul SNMP Suite?
&lt;/h2&gt;

&lt;p&gt;It's a self-hosted SNMP dev toolkit that combines five tools into one clean web UI:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;Instead of&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SNMP Simulator (UDP agent)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;snmpsim&lt;/code&gt; + CLI config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Walk &amp;amp; Parse → JSON&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;snmpwalk&lt;/code&gt; + manual OID lookup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trap Sender + Receiver&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;snmptrap&lt;/code&gt; + &lt;code&gt;snmptrapd&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MIB Browser (tree view)&lt;/td&gt;
&lt;td&gt;iReasoning MIB Browser ($500+)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MIB Manager (upload/validate)&lt;/td&gt;
&lt;td&gt;Text editor + manual dependency hell&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; Python 3.11, FastAPI, pysnmp, pysmi, Bootstrap 5, Docker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install in one command&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/tosumitdhaka/trishul-snmp-suite/main/install-trishul-snmp-suite.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open &lt;code&gt;http://localhost:8080&lt;/code&gt;. Default login: &lt;code&gt;admin&lt;/code&gt; / &lt;code&gt;admin123&lt;/code&gt; — change it immediately in Settings.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's New in v1.2.4
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ⚡ Real-Time WebSocket Push — Polling Is Dead
&lt;/h3&gt;

&lt;p&gt;The biggest architectural change: the entire frontend is now event-driven.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Every page polled the backend on a &lt;code&gt;setInterval&lt;/code&gt; — dashboard every 30s, simulator every 5s. Stale data was common. Switching pages caused spinners.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; A single persistent WebSocket connection at &lt;code&gt;/api/ws&lt;/code&gt;. The backend broadcasts state changes the moment they happen. Dashboard, Simulator status, and Trap Receiver all update instantly — no refresh needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser ←──── WS push ────── FastAPI /api/ws
                                    │
                              broadcasts on:
                              - trap received
                              - simulator start/stop
                              - MIB uploaded
                              - stats change
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The navbar shows a live green dot when the WebSocket is healthy. On reconnect, the backend sends a &lt;code&gt;full_state&lt;/code&gt; message to re-seed everything — so you never see stale data after a network hiccup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this matters for devs:&lt;/strong&gt; If you're building a trap handler and sending test traps from the UI, you now see the counter increment on the dashboard in real time. No F5 needed.&lt;/p&gt;




&lt;h3&gt;
  
  
  📊 Live Activity Stats Dashboard
&lt;/h3&gt;

&lt;p&gt;A new 8-counter row on the dashboard shows everything happening in your session:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SNMP Requests&lt;/strong&gt; — Total polls served by the simulator&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OIDs Loaded&lt;/strong&gt; — OIDs currently in memory across all loaded MIBs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traps Received / Sent&lt;/strong&gt; — Live trap counters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Walks Executed&lt;/strong&gt; — How many SNMP walks you've run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OIDs Returned&lt;/strong&gt; — Total OIDs returned across all walks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIBs Uploaded / Times Reloaded&lt;/strong&gt; — MIB management activity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All counters update via WebSocket push. They're also &lt;strong&gt;file-backed&lt;/strong&gt; — they survive container restarts so you don't lose your session history.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚙️ Settings — Three New Cards
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;App Behaviour&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two toggles: auto-start Simulator and auto-start Trap Receiver on container boot. Plus a configurable session timeout (60s–86400s). Settings persist to &lt;code&gt;app_settings.json&lt;/code&gt; and take effect on next restart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stats Management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Export all counters as JSON (useful for logging test session results) or reset to zero for a clean baseline before a test run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;About&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Version, author, and description pulled live from the backend — always in sync with what's actually deployed.&lt;/p&gt;




&lt;h3&gt;
  
  
  🐛 Notable Fixes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Timestamp bug:&lt;/strong&gt; The Trap Receiver was showing &lt;code&gt;1970&lt;/code&gt; for &lt;code&gt;Last Received&lt;/code&gt; when the backend returned a Unix epoch &lt;code&gt;0&lt;/code&gt;. Now guarded and shown as &lt;code&gt;--&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traps Sent undercount:&lt;/strong&gt; Stats were only incremented in the frontend — if you sent traps via API directly, the counter never moved. Fixed by broadcasting stats from the backend after every successful trap send.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dashboard spinners on page switch:&lt;/strong&gt; The WS &lt;code&gt;full_state&lt;/code&gt; event fires before &lt;code&gt;DashboardModule.init()&lt;/code&gt; registers its listener on page switch, so status tiles stayed as spinners until the next reconnect. Fixed by always seeding via REST on init, regardless of WS state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MIB Browser state conflict:&lt;/strong&gt; Navigating to the Browser from Walk &amp;amp; Parse (with a pre-filled OID) would sometimes log &lt;code&gt;Could not find node&lt;/code&gt; because the previous session's pending tree state conflicted. Fixed by clearing &lt;code&gt;pendingSelectedOid&lt;/code&gt; and &lt;code&gt;pendingExpandedNodes&lt;/code&gt; when a programmatic OID search is present.&lt;/p&gt;




&lt;h2&gt;
  
  
  Who Is This For?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;NMS / backend developers&lt;/strong&gt; who need a real SNMP agent to poll without actual hardware, or need to fire specific trap OIDs to validate their handler code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DevOps / integration engineers&lt;/strong&gt; who need to test SNMP monitoring integrations in CI/staging environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network engineers&lt;/strong&gt; who want to explore MIB structures interactively — search by OID, by name, or by description — and understand what traps a device can fire before it's on the floor.&lt;/p&gt;

&lt;h3&gt;
  
  
  What It's NOT For
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Production 24/7 monitoring → use Zabbix, LibreNMS, PRTG&lt;/li&gt;
&lt;li&gt;Enterprise NMS → use SolarWinds, Cisco Prime&lt;/li&gt;
&lt;li&gt;High-availability trap collection at scale → use dedicated platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trishul is a &lt;strong&gt;developer and testing tool&lt;/strong&gt;, not a production monitoring system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser (8080)
    │ HTTP + WebSocket
    ▼
Nginx (static files + reverse proxy)
    │ REST + WS
    ▼
FastAPI Backend (8000)
    ├── MIB Service (parse, validate, search)
    ├── SNMP Simulator (UDP 1061)
    ├── Trap Manager (send + receive on UDP 1162)
    ├── Walker (SNMP walk client)
    └── WebSocket hub (/api/ws)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything runs in Docker with host network mode so the SNMP UDP ports (1061, 1162) are accessible directly from your local machine or test devices.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# One-command install&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/tosumitdhaka/trishul-snmp-suite/main/install-trishul-snmp-suite.sh | bash

&lt;span class="c"&gt;# Access at&lt;/span&gt;
http://localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;🐙 &lt;a href="https://github.com/tosumitdhaka/trishul-snmp-suite" rel="noopener noreferrer"&gt;GitHub — tosumitdhaka/trishul-snmp-suite&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💬 &lt;a href="https://github.com/tosumitdhaka/trishul-snmp-suite/discussions/20" rel="noopener noreferrer"&gt;v1.2.4 Announcement &amp;amp; Discussion&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it's useful, a ⭐ on GitHub goes a long way — it helps other devs find the project.&lt;/p&gt;

&lt;p&gt;Happy to answer questions in the comments about architecture decisions, the pysnmp/pysmi integration, or the WebSocket implementation. 🔱&lt;/p&gt;

</description>
      <category>networking</category>
      <category>python</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Created OpenSource SNMP dev/testing tool for devs, please checkout and help improving it.</title>
      <dc:creator>Sumit Dhaka</dc:creator>
      <pubDate>Sun, 22 Feb 2026 12:40:19 +0000</pubDate>
      <link>https://forem.com/tosumitdhaka/created-opensource-snmp-devtesting-tool-for-devs-please-checkout-and-help-improving-it-4mjh</link>
      <guid>https://forem.com/tosumitdhaka/created-opensource-snmp-devtesting-tool-for-devs-please-checkout-and-help-improving-it-4mjh</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-that-replaces-500-tools-now-with-real-time-websocket-38p6" class="crayons-story__hidden-navigation-link"&gt;I Built a Free, Self-Hosted SNMP Toolkit — Now With Real-Time WebSocket Push&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/tosumitdhaka" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3763376%2Fe5732a10-8442-4a4d-bbb4-176b093db048.jpg" alt="tosumitdhaka profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/tosumitdhaka" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Sumit Dhaka
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Sumit Dhaka
                
              
              &lt;div id="story-author-preview-content-3275073" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/tosumitdhaka" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3763376%2Fe5732a10-8442-4a4d-bbb4-176b093db048.jpg" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Sumit Dhaka&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-that-replaces-500-tools-now-with-real-time-websocket-38p6" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 22&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-that-replaces-500-tools-now-with-real-time-websocket-38p6" id="article-link-3275073"&gt;
          I Built a Free, Self-Hosted SNMP Toolkit — Now With Real-Time WebSocket Push
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/networking"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;networking&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-that-replaces-500-tools-now-with-real-time-websocket-38p6" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;3&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-that-replaces-500-tools-now-with-real-time-websocket-38p6#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>networking</category>
      <category>python</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Sumit Dhaka</dc:creator>
      <pubDate>Sun, 22 Feb 2026 12:38:49 +0000</pubDate>
      <link>https://forem.com/tosumitdhaka/-11l3</link>
      <guid>https://forem.com/tosumitdhaka/-11l3</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/tosumitdhaka/building-trishul-snmp-a-modern-web-based-snmp-toolkit-to-replace-500-commercial-tools-3d53" class="crayons-story__hidden-navigation-link"&gt;Building Trishul-SNMP-Suite: A Modern Web-Based SNMP Toolkit to Replace $500 Commercial Tools&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/tosumitdhaka" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3763376%2Fe5732a10-8442-4a4d-bbb4-176b093db048.jpg" alt="tosumitdhaka profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/tosumitdhaka" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Sumit Dhaka
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Sumit Dhaka
                
              
              &lt;div id="story-author-preview-content-3245855" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/tosumitdhaka" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3763376%2Fe5732a10-8442-4a4d-bbb4-176b093db048.jpg" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Sumit Dhaka&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/tosumitdhaka/building-trishul-snmp-a-modern-web-based-snmp-toolkit-to-replace-500-commercial-tools-3d53" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 10&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/tosumitdhaka/building-trishul-snmp-a-modern-web-based-snmp-toolkit-to-replace-500-commercial-tools-3d53" id="article-link-3245855"&gt;
          Building Trishul-SNMP-Suite: A Modern Web-Based SNMP Toolkit to Replace $500 Commercial Tools
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/snmp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;snmp&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/networking"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;networking&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/tosumitdhaka/building-trishul-snmp-a-modern-web-based-snmp-toolkit-to-replace-500-commercial-tools-3d53" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/tosumitdhaka/building-trishul-snmp-a-modern-web-based-snmp-toolkit-to-replace-500-commercial-tools-3d53#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            8 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>snmp</category>
      <category>networking</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>I Built a Free, Self-Hosted SNMP Toolkit — Now With Real-Time WebSocket Push</title>
      <dc:creator>Sumit Dhaka</dc:creator>
      <pubDate>Sun, 22 Feb 2026 12:38:22 +0000</pubDate>
      <link>https://forem.com/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-that-replaces-500-tools-now-with-real-time-websocket-38p6</link>
      <guid>https://forem.com/tosumitdhaka/i-built-a-free-self-hosted-snmp-toolkit-that-replaces-500-tools-now-with-real-time-websocket-38p6</guid>
      <description>&lt;p&gt;If you've ever worked with SNMP — testing NMS integrations, debugging trap handlers, or validating MIB structures — you know the pain. You end up juggling Net-SNMP CLI commands you can never remember, &lt;code&gt;snmptrapd&lt;/code&gt; configs scattered everywhere, and a $500 MIB browser that still looks like it was designed in 2003.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;Trishul SNMP Studio&lt;/strong&gt; to fix that. One Docker container. Browser-based. Free.&lt;/p&gt;

&lt;p&gt;This post covers what's new in &lt;strong&gt;v1.2.4&lt;/strong&gt; — the biggest update yet — and why I built it this way.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is Trishul SNMP Studio?
&lt;/h2&gt;

&lt;p&gt;It's a self-hosted SNMP dev toolkit that combines five tools into one clean web UI:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;Instead of&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SNMP Simulator (UDP agent)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;snmpsim&lt;/code&gt; + CLI config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Walk &amp;amp; Parse → JSON&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;snmpwalk&lt;/code&gt; + manual OID lookup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trap Sender + Receiver&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;snmptrap&lt;/code&gt; + &lt;code&gt;snmptrapd&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MIB Browser (tree view)&lt;/td&gt;
&lt;td&gt;iReasoning MIB Browser ($500+)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MIB Manager (upload/validate)&lt;/td&gt;
&lt;td&gt;Text editor + manual dependency hell&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; Python 3.11, FastAPI, pysnmp, pysmi, Bootstrap 5, Docker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install in one command&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/tosumitdhaka/trishul-snmp/main/install-trishul-snmp.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open &lt;code&gt;http://localhost:8080&lt;/code&gt;. Default login: &lt;code&gt;admin&lt;/code&gt; / &lt;code&gt;admin123&lt;/code&gt; — change it immediately in Settings.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's New in v1.2.4
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ⚡ Real-Time WebSocket Push — Polling Is Dead
&lt;/h3&gt;

&lt;p&gt;The biggest architectural change: the entire frontend is now event-driven.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Every page polled the backend on a &lt;code&gt;setInterval&lt;/code&gt; — dashboard every 30s, simulator every 5s. Stale data was common. Switching pages caused spinners.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; A single persistent WebSocket connection at &lt;code&gt;/api/ws&lt;/code&gt;. The backend broadcasts state changes the moment they happen. Dashboard, Simulator status, and Trap Receiver all update instantly — no refresh needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser ←──── WS push ────── FastAPI /api/ws
                                    │
                              broadcasts on:
                              - trap received
                              - simulator start/stop
                              - MIB uploaded
                              - stats change
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The navbar shows a live green dot when the WebSocket is healthy. On reconnect, the backend sends a &lt;code&gt;full_state&lt;/code&gt; message to re-seed everything — so you never see stale data after a network hiccup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this matters for devs:&lt;/strong&gt; If you're building a trap handler and sending test traps from the UI, you now see the counter increment on the dashboard in real time. No F5 needed.&lt;/p&gt;




&lt;h3&gt;
  
  
  📊 Live Activity Stats Dashboard
&lt;/h3&gt;

&lt;p&gt;A new 8-counter row on the dashboard shows everything happening in your session:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SNMP Requests&lt;/strong&gt; — Total polls served by the simulator&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OIDs Loaded&lt;/strong&gt; — OIDs currently in memory across all loaded MIBs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traps Received / Sent&lt;/strong&gt; — Live trap counters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Walks Executed&lt;/strong&gt; — How many SNMP walks you've run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OIDs Returned&lt;/strong&gt; — Total OIDs returned across all walks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIBs Uploaded / Times Reloaded&lt;/strong&gt; — MIB management activity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All counters update via WebSocket push. They're also &lt;strong&gt;file-backed&lt;/strong&gt; — they survive container restarts so you don't lose your session history.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚙️ Settings — Three New Cards
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;App Behaviour&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two toggles: auto-start Simulator and auto-start Trap Receiver on container boot. Plus a configurable session timeout (60s–86400s). Settings persist to &lt;code&gt;app_settings.json&lt;/code&gt; and take effect on next restart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stats Management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Export all counters as JSON (useful for logging test session results) or reset to zero for a clean baseline before a test run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;About&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Version, author, and description pulled live from the backend — always in sync with what's actually deployed.&lt;/p&gt;




&lt;h3&gt;
  
  
  🐛 Notable Fixes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Timestamp bug:&lt;/strong&gt; The Trap Receiver was showing &lt;code&gt;1970&lt;/code&gt; for &lt;code&gt;Last Received&lt;/code&gt; when the backend returned a Unix epoch &lt;code&gt;0&lt;/code&gt;. Now guarded and shown as &lt;code&gt;--&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traps Sent undercount:&lt;/strong&gt; Stats were only incremented in the frontend — if you sent traps via API directly, the counter never moved. Fixed by broadcasting stats from the backend after every successful trap send.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dashboard spinners on page switch:&lt;/strong&gt; The WS &lt;code&gt;full_state&lt;/code&gt; event fires before &lt;code&gt;DashboardModule.init()&lt;/code&gt; registers its listener on page switch, so status tiles stayed as spinners until the next reconnect. Fixed by always seeding via REST on init, regardless of WS state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MIB Browser state conflict:&lt;/strong&gt; Navigating to the Browser from Walk &amp;amp; Parse (with a pre-filled OID) would sometimes log &lt;code&gt;Could not find node&lt;/code&gt; because the previous session's pending tree state conflicted. Fixed by clearing &lt;code&gt;pendingSelectedOid&lt;/code&gt; and &lt;code&gt;pendingExpandedNodes&lt;/code&gt; when a programmatic OID search is present.&lt;/p&gt;




&lt;h2&gt;
  
  
  Who Is This For?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;NMS / backend developers&lt;/strong&gt; who need a real SNMP agent to poll without actual hardware, or need to fire specific trap OIDs to validate their handler code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DevOps / integration engineers&lt;/strong&gt; who need to test SNMP monitoring integrations in CI/staging environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network engineers&lt;/strong&gt; who want to explore MIB structures interactively — search by OID, by name, or by description — and understand what traps a device can fire before it's on the floor.&lt;/p&gt;

&lt;h3&gt;
  
  
  What It's NOT For
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Production 24/7 monitoring → use Zabbix, LibreNMS, PRTG&lt;/li&gt;
&lt;li&gt;Enterprise NMS → use SolarWinds, Cisco Prime&lt;/li&gt;
&lt;li&gt;High-availability trap collection at scale → use dedicated platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trishul is a &lt;strong&gt;developer and testing tool&lt;/strong&gt;, not a production monitoring system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser (8080)
    │ HTTP + WebSocket
    ▼
Nginx (static files + reverse proxy)
    │ REST + WS
    ▼
FastAPI Backend (8000)
    ├── MIB Service (parse, validate, search)
    ├── SNMP Simulator (UDP 1061)
    ├── Trap Manager (send + receive on UDP 1162)
    ├── Walker (SNMP walk client)
    └── WebSocket hub (/api/ws)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything runs in Docker with host network mode so the SNMP UDP ports (1061, 1162) are accessible directly from your local machine or test devices.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# One-command install&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/tosumitdhaka/trishul-snmp/main/install-trishul-snmp.sh | bash

&lt;span class="c"&gt;# Access at&lt;/span&gt;
http://localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;🐙 &lt;a href="https://github.com/tosumitdhaka/trishul-snmp" rel="noopener noreferrer"&gt;GitHub — tosumitdhaka/trishul-snmp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💬 &lt;a href="https://github.com/tosumitdhaka/trishul-snmp/discussions/20" rel="noopener noreferrer"&gt;v1.2.4 Announcement &amp;amp; Discussion&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📋 &lt;a href="https://github.com/tosumitdhaka/trishul-snmp/wiki/Changelog" rel="noopener noreferrer"&gt;Full Changelog&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it's useful, a ⭐ on GitHub goes a long way — it helps other devs find the project.&lt;/p&gt;

&lt;p&gt;Happy to answer questions in the comments about architecture decisions, the pysnmp/pysmi integration, or the WebSocket implementation. 🔱&lt;/p&gt;

</description>
      <category>networking</category>
      <category>python</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building Trishul-SNMP-Suite: A Modern Web-Based SNMP Toolkit to Replace $500 Commercial Tools</title>
      <dc:creator>Sumit Dhaka</dc:creator>
      <pubDate>Tue, 10 Feb 2026 08:45:14 +0000</pubDate>
      <link>https://forem.com/tosumitdhaka/building-trishul-snmp-a-modern-web-based-snmp-toolkit-to-replace-500-commercial-tools-3d53</link>
      <guid>https://forem.com/tosumitdhaka/building-trishul-snmp-a-modern-web-based-snmp-toolkit-to-replace-500-commercial-tools-3d53</guid>
      <description>&lt;h2&gt;
  
  
  Building Trishul SNMP Suite: A Modern Web-Based SNMP Toolkit
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;Trishul SNMP Suite&lt;/strong&gt; 🔱, a free open-source web-based SNMP toolkit that replaces 5+ commercial tools. It includes an SNMP simulator, walker, trap manager, MIB browser, and more—all in one unified platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔗 GitHub:&lt;/strong&gt; &lt;a href="https://github.com/tosumitdhaka/trishul-snmp-suite" rel="noopener noreferrer"&gt;https://github.com/tosumitdhaka/trishul-snmp-suite&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;⭐ Star it if you find it useful!&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The Problem: SNMP Tooling is Stuck in the Past
&lt;/h2&gt;

&lt;p&gt;As a network engineer, I was frustrated with the state of SNMP tooling:&lt;/p&gt;
&lt;h3&gt;
  
  
  What's Available Today:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Net-SNMP&lt;/strong&gt; 🐌&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Powerful but CLI-only&lt;/li&gt;
&lt;li&gt;Steep learning curve&lt;/li&gt;
&lt;li&gt;Need to memorize commands&lt;/li&gt;
&lt;li&gt;No visual feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;iReasoning MIB Browser&lt;/strong&gt; 💰&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Great GUI but costs &lt;strong&gt;$500+&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Desktop app (not web-based)&lt;/li&gt;
&lt;li&gt;No trap receiver&lt;/li&gt;
&lt;li&gt;Closed source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;snmpsim&lt;/strong&gt; 🔧&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Good simulator but no web interface&lt;/li&gt;
&lt;li&gt;CLI configuration&lt;/li&gt;
&lt;li&gt;Limited features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Custom Scripts&lt;/strong&gt; 📝&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scattered across repos&lt;/li&gt;
&lt;li&gt;Hard to maintain&lt;/li&gt;
&lt;li&gt;No unified workflow&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What I Needed:
&lt;/h3&gt;

&lt;p&gt;✅ &lt;strong&gt;Web-based&lt;/strong&gt; (access from anywhere)&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Free &amp;amp; open source&lt;/strong&gt; (no $500 license)&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Unified platform&lt;/strong&gt; (one tool for everything)&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Modern UI&lt;/strong&gt; (not from 2005)&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Easy deployment&lt;/strong&gt; (Docker one-liner)  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So I built it.&lt;/strong&gt; 🔱&lt;/p&gt;


&lt;h2&gt;
  
  
  Introducing Trishul SNMP Suite
&lt;/h2&gt;

&lt;p&gt;A web-based SNMP toolkit with &lt;strong&gt;6 integrated components&lt;/strong&gt;:&lt;/p&gt;
&lt;h3&gt;
  
  
  🖥️ 1. SNMP Simulator (Server Mode)
&lt;/h3&gt;

&lt;p&gt;Test SNMP agent responses without real hardware.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start simulator with custom OIDs&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8000/api/simulator/start &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "port": 1061,
    "community": "public",
    "oids": {
      "1.3.6.1.2.1.1.1.0": "Test Device v1.0",
      "1.3.6.1.2.1.1.3.0": "12345"
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Simulate devices for NMS development and testing.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚶 2. Walk &amp;amp; Parse (Client Mode)
&lt;/h3&gt;

&lt;p&gt;Test SNMP queries with automatic MIB resolution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Walk a device&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8000/api/walker/walk &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "host": "192.168.1.1",
    "community": "public",
    "oid": "1.3.6.1.2.1.1",
    "version": "2c"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic OID → name resolution&lt;/li&gt;
&lt;li&gt;Export to JSON/CSV&lt;/li&gt;
&lt;li&gt;Bulk operations (GETBULK)&lt;/li&gt;
&lt;li&gt;Walk history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Test SNMP agent responses, validate walk implementations.&lt;/p&gt;




&lt;h3&gt;
  
  
  📡 3. Trap Manager (Client + Server)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Send Test Traps (Client):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Send trap to test receiver&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8000/api/traps/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "target": "192.168.1.100",
    "port": 162,
    "community": "public",
    "trap_oid": "1.3.6.1.6.3.1.1.5.3",
    "varbinds": [
      {"oid": "1.3.6.1.2.1.1.3.0", "value": "12345"}
    ]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Receive Test Traps (Server):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time display on UDP 1162&lt;/li&gt;
&lt;li&gt;Automatic OID resolution&lt;/li&gt;
&lt;li&gt;Trap library with 24+ traps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Validate trap format/syntax for NMS development.&lt;/p&gt;




&lt;h3&gt;
  
  
  📚 4. MIB Manager
&lt;/h3&gt;

&lt;p&gt;Upload and validate MIB files with dependency checking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag-and-drop upload&lt;/li&gt;
&lt;li&gt;Syntax validation&lt;/li&gt;
&lt;li&gt;Dependency resolution&lt;/li&gt;
&lt;li&gt;Trap enumeration&lt;/li&gt;
&lt;li&gt;Statistics (objects, imports, traps)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Validate MIBs before deployment, centralized MIB library.&lt;/p&gt;




&lt;h3&gt;
  
  
  🌳 5. MIB Browser (NEW in v1.2.0!)
&lt;/h3&gt;

&lt;p&gt;Interactive tree explorer for MIB structures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dual views:&lt;/strong&gt; By module or OID hierarchy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time search:&lt;/strong&gt; Find OIDs by name, numeric OID, or description&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart filtering:&lt;/strong&gt; By module and type (scalars, tables, notifications)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tree navigation:&lt;/strong&gt; Expandable with configurable depth (1-5 levels)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Details panel:&lt;/strong&gt; Full metadata, descriptions, varbinds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration:&lt;/strong&gt; Jump to Walker/Trap Sender with pre-filled data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State persistence:&lt;/strong&gt; Remembers your position&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Explore MIB structures, understand OID relationships, find traps.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔐 6. Settings
&lt;/h3&gt;

&lt;p&gt;Manage authentication and preferences.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture: How It Works
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────────┐
│                      Web Browser (Port 8080)                        │
│                                                                     │
│  ┌──────────┐ ┌──────────┐ ┌───────┐ ┌──────┐ ┌────────┐ ┌─────┐    │
│  │Dashboard │ │Simulator │ │Walker │ │Traps │ │Browser │ │MIBs │    │
│  └──────────┘ └──────────┘ └───────┘ └──────┘ └────────┘ └─────┘    │
└────────────────────────────┬────────────────────────────────────────┘
                             │ HTTP
                             │
              ┌──────────────▼──────────────┐
              │   Nginx (Frontend)          │
              │   • Serves static files     │
              │   • Reverse proxy to API    │
              └──────────────┬──────────────┘
                             │ REST API
                             │
┌────────────────────────────▼────────────────────────────────────────┐
│                  FastAPI Backend (Port 8000)                        │
│                                                                     │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │                      API Endpoints                            │  │
│  │  /api/simulator/*  /api/walker/*   /api/traps/*               │  │
│  │  /api/mibs/*       /api/browser/*  /api/settings/*            │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │                    Service Layer                              │  │
│  │                                                               │  │
│  │  ┌─────────────────────────────────────────────────────────┐  │  │
│  │  │              MIB Service (pysmi/pysnmp)                 │  │  │
│  │  │  • Parse &amp;amp; validate MIB files                           │  │  │
│  │  │  • Check syntax &amp;amp; dependencies                          │  │  │
│  │  │  • Build OID tree (module/hierarchy views)              │  │  │
│  │  │  • Resolve OID names ↔ numeric OIDs                     │  │  │
│  │  │  • Enumerate traps (24: 19 loaded + 5 system)           │  │  │
│  │  │  • Search &amp;amp; filter (name, OID, type, module)            │  │  │
│  │  └─────────────────────────────────────────────────────────┘  │  │
│  │                                                               │  │
│  │  ┌─────────────────────────────────────────────────────────┐  │  │
│  │  │              SNMP Service (pysnmp)                      │  │  │
│  │  │  • Simulator: Test SNMP agent responses                 │  │  │
│  │  │  • Walker: Test SNMP client queries                     │  │  │
│  │  │  • Trap Sender: Send test traps (client)                │  │  │
│  │  │  • Trap Receiver: Receive test traps (server)           │  │  │
│  │  └─────────────────────────────────────────────────────────┘  │  │
│  │                                                               │  │
│  │  ┌─────────────────────────────────────────────────────────┐  │  │
│  │  │              Auth Service                               │  │  │
│  │  │  • Session management (token-based)                     │  │  │
│  │  │  • User authentication                                  │  │  │
│  │  └─────────────────────────────────────────────────────────┘  │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │                    SNMP Network Layer                         │  │
│  │                                                               │  │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐       │  │
│  │  │Simulator │  │  Sender  │  │ Receiver │  │  Walker  │       │  │
│  │  │  (SVR)   │  │  (CLI)   │  │  (SVR)   │  │  (CLI)   │       │  │
│  │  │UDP: 1061 │  │ Dynamic  │  │UDP: 1162 │  │ Dynamic  │       │  │
│  │  │          │  │          │  │          │  │          │       │  │
│  │  │Test SNMP │  │Send test │  │Receive   │  │Test SNMP │       │  │
│  │  │agent     │  │traps to  │  │test traps│  │queries   │       │  │
│  │  │responses │  │dev/test  │  │from dev/ │  │to dev/   │       │  │
│  │  │          │  │targets   │  │test env  │  │test env  │       │  │
│  │  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘       │  │
│  │       │             │             │             │             │  │
│  └───────┼─────────────┼─────────────┼─────────────┼─────────────┘  │
│          │             │             │             │                │
│  ┌───────▼─────────────▼─────────────▼─────────────▼─────────────┐  │
│  │              Data Storage (Docker Volume)                     │  │
│  │  /app/data/                                                   │  │
│  │    ├── mibs/           (MIB files for validation)             │  │
│  │    ├── sessions.json   (Auth tokens)                          │  │
│  │    └── settings.json   (User config)                          │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                                                     │
└───────────────────────────┬─────────────────────────────────────────┘
                            │ SNMP Protocol (UDP)
                            │ Host Network Mode
                            │
             ┌──────────────┴──────────────┐
             │                             │
     ┌───────▼────────┐           ┌────────▼────────┐
     │ Test SNMP      │           │  Test Trap      │
     │ Clients/Agents │           │  Receivers      │
     │ (Dev/Test Env) │           │  (Dev/Test Env) │
     │                │           │                 │
     │ • Your NMS     │           │ • Your NMS      │
     │ • Custom apps  │           │ • Trap parsers  │
     │ • Test devices │           │ • Log servers   │
     │ • Simulators   │           │ • Test apps     │
     └────────────────┘           └─────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tech Stack:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Python 3.11, FastAPI, pysnmp, pysmi&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Vanilla JS, Bootstrap 5&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment:&lt;/strong&gt; Docker Compose, Nginx&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage:&lt;/strong&gt; Docker volumes for persistence&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Key Technical Decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Host Network Mode for SNMP
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; SNMP uses dynamic UDP ports. Traps can come from any port, not just 162.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Use Docker's host network mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# docker-compose.yml&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;network_mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;host"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8000:8000"&lt;/span&gt;  &lt;span class="c1"&gt;# API&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1061:1061/udp"&lt;/span&gt;  &lt;span class="c1"&gt;# Simulator&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1162:1162/udp"&lt;/span&gt;  &lt;span class="c1"&gt;# Trap receiver&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Trade-off:&lt;/strong&gt; Less isolation, but necessary for SNMP's dynamic nature.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. MIB Parsing with pysmi
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; MIBs have complex dependencies (IMPORTS clause).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Use pysmi's MibBuilder with custom sources.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pysmi.reader&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FileReader&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pysmi.searcher&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StubSearcher&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pysnmp.smi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize MIB builder
&lt;/span&gt;&lt;span class="n"&gt;mib_builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MibBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Add custom MIB directory
&lt;/span&gt;&lt;span class="n"&gt;mib_builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMibSources&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;FileReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/app/data/mibs&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Load MIB with automatic dependency resolution
&lt;/span&gt;&lt;span class="n"&gt;mib_builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadModules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;IF-MIB&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Access MIB objects
&lt;/span&gt;&lt;span class="n"&gt;mib_view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MibViewController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mib_builder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Automatic dependency resolution—upload IF-MIB, and it automatically finds SNMPv2-SMI, SNMPv2-TC, etc.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. State Persistence Across Pages
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Users lose context when switching between components (e.g., Browser → Walker).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; SessionStorage for UI state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Save state when leaving page&lt;/span&gt;
&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;browserState&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;view&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IF-MIB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ifDescr&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;expandedNodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.3.6.1.2.1.2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;selectedOid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.3.6.1.2.1.2.2.1.2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="c1"&gt;// Restore state on page load&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DOMContentLoaded&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;browserState&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Restore view, search, expanded nodes, selection&lt;/span&gt;
        &lt;span class="nf"&gt;restoreState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Seamless navigation. Browse a trap in MIB Browser → click "Send this Trap" → Trap Sender opens with trap pre-filled → click "Browse" → returns to same position in tree.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Performance: Backend Caching
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Listing 24 traps on every dashboard load is slow (parses all MIBs).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; In-memory cache with 60-second TTL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MibService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_trap_cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_trap_cache_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_trap_cache_ttl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;  &lt;span class="c1"&gt;# seconds
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_traps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;current_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# Return cached data if fresh
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_trap_cache&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_time&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_trap_cache_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_trap_cache_ttl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_trap_cache&lt;/span&gt;

        &lt;span class="c1"&gt;# Build fresh list
&lt;/span&gt;        &lt;span class="n"&gt;traps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_build_trap_list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# Update cache
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_trap_cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;traps&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_trap_cache_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_time&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;traps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Dashboard load time reduced from 2s → 0.2s (10x faster).&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Lazy Loading for MIB Tree
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Rendering 1000+ OIDs at once freezes the browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Load children on-demand with configurable depth.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;expandNodeRecursively&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nodeEl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nodeEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Load only immediate children&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/mibs/browse/tree/oid?root_oid=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;oid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;depth=1`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Render children&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;childrenContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nodeEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.tree-children&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;childrenContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;buildTreeNodeHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Recursively expand if depth &amp;gt; 1&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;childNodes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;childrenContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.tree-node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;childNode&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;childNodes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expandNodeRecursively&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;childNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User selects depth: 1-5 levels (default: 3)&lt;/li&gt;
&lt;li&gt;Only visible nodes rendered&lt;/li&gt;
&lt;li&gt;Smooth expansion even with large MIBs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Can handle MIBs with 5000+ objects without lag.&lt;/p&gt;




&lt;h2&gt;
  
  
  Challenges &amp;amp; Solutions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Challenge 1: Trap Count Inconsistency
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Dashboard showed 24 traps, MIB Manager showed 19.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root cause:&lt;/strong&gt; System MIBs (SNMPv2-MIB, RMON-MIB) are built into pysnmp but not in the "loaded MIB" list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Visual distinction with badges.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;knownSystemMibs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SNMPv2-MIB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RMON-MIB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IF-MIB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadedModules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loadedMibs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;traps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trap&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isSystemMib&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;knownSystemMibs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
                        &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;loadedModules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Gray badge for system MIBs, blue for loaded&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;badge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;span class="badge &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;isSystemMib&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;
            &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
        &amp;lt;/span&amp;gt;
        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;isSystemMib&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;span class="badge bg-secondary"&amp;gt;System&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Clear distinction—users understand which MIBs are built-in vs. uploaded.&lt;/p&gt;




&lt;h3&gt;
  
  
  Challenge 2: Docker Image Size
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Initial image was 1.2GB (too large for quick pulls).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Multi-stage builds + Alpine base.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;python:3.11-slim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# Runtime stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.11-alpine&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Copy only installed packages&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /root/.local /root/.local&lt;/span&gt;

&lt;span class="c"&gt;# Copy application&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# Set PATH&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PATH=/root/.local/bin:$PATH&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Image size reduced to &lt;strong&gt;350MB&lt;/strong&gt; (70% smaller).&lt;/p&gt;




&lt;h3&gt;
  
  
  Challenge 3: MIB Browser Tree Performance
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Expanding large MIBs (e.g., CISCO-SMI with 3000+ objects) caused browser freeze.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions implemented:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Lazy loading:&lt;/strong&gt; Load children only when node is expanded&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Depth control:&lt;/strong&gt; User chooses 1-5 levels (prevents over-expansion)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debounced search:&lt;/strong&gt; 500ms delay to avoid excessive API calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtual scrolling:&lt;/strong&gt; Only render visible nodes (future enhancement)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Debounced search&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;searchTimeout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;searchInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTimeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;searchTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;performSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Wait 500ms after user stops typing&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Smooth navigation even with 5000+ object MIBs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Start with MVP, Iterate Based on Feedback
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;v1.0.0&lt;/strong&gt; (June 2025):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4 components: Simulator, Walker, Traps, MIB Manager&lt;/li&gt;
&lt;li&gt;Basic functionality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;v1.2.0&lt;/strong&gt; (Feb 2026):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added MIB Browser (most requested feature)&lt;/li&gt;
&lt;li&gt;Enhanced trap management&lt;/li&gt;
&lt;li&gt;State persistence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Ship early, listen to users, add features they actually need.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Documentation is as Important as Code
&lt;/h3&gt;

&lt;p&gt;I spent &lt;strong&gt;20% of development time&lt;/strong&gt; on documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Comprehensive README&lt;/li&gt;
&lt;li&gt;Architecture diagrams&lt;/li&gt;
&lt;li&gt;API documentation (FastAPI auto-docs)&lt;/li&gt;
&lt;li&gt;Code comments&lt;/li&gt;
&lt;li&gt;Contributing guidelines&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. One-Command Install is Crucial
&lt;/h3&gt;

&lt;p&gt;Users won't read complex setup instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone repo&lt;/span&gt;
git clone ...
&lt;span class="nb"&gt;cd &lt;/span&gt;trishul-snmp

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Configure&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
vim .env

&lt;span class="c"&gt;# Build&lt;/span&gt;
docker-compose build

&lt;span class="c"&gt;# Run&lt;/span&gt;
docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Good:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/tosumitdhaka/trishul-snmp-suite/main/install-trishul-snmp-suite.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Lower barrier to entry = more users trying it.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Open Source ≠ Free Labor
&lt;/h3&gt;

&lt;p&gt;Be clear about support expectations:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Added:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code of Conduct&lt;/li&gt;
&lt;li&gt;Contributing guidelines&lt;/li&gt;
&lt;li&gt;Issue templates&lt;/li&gt;
&lt;li&gt;Pull request template&lt;/li&gt;
&lt;li&gt;License (MIT)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Set boundaries:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Response time: "Best effort, usually within 48 hours"&lt;/li&gt;
&lt;li&gt;Feature requests: "Vote on issues, no guarantees"&lt;/li&gt;
&lt;li&gt;Support: "Community-driven, use Discussions"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Protect your time while being welcoming.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Community Matters
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What worked:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Discussions for Q&amp;amp;A&lt;/li&gt;
&lt;li&gt;Twitter/LinkedIn posts&lt;/li&gt;
&lt;li&gt;Dev.to articles (like this one!)&lt;/li&gt;
&lt;li&gt;Responding to every comment/issue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What didn't:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discord server (too early, not enough users)&lt;/li&gt;
&lt;li&gt;Weekly newsletters (too much overhead)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Focus on platforms where your users already are.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results (2 Months After Launch)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;⭐ &lt;strong&gt;19+ GitHub stars&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🍴 &lt;strong&gt;2+ forks&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🐳 &lt;strong&gt;100+ Docker pulls&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Next? v1.3.0 Roadmap
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🚧 In Progress:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔐 &lt;strong&gt;SNMPv3 authentication&lt;/strong&gt; (MD5, SHA, AES encryption)&lt;/li&gt;
&lt;li&gt;⏰ &lt;strong&gt;Scheduled SNMP walks&lt;/strong&gt; (cron-like syntax)&lt;/li&gt;
&lt;li&gt;📧 &lt;strong&gt;Notifications&lt;/strong&gt; (Email/Slack/Webhook for traps)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📋 Planned:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📊 &lt;strong&gt;Custom dashboards&lt;/strong&gt; (drag-and-drop widgets)&lt;/li&gt;
&lt;li&gt;🔑 &lt;strong&gt;API keys&lt;/strong&gt; (rate limiting, authentication)&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;Bulk device management&lt;/strong&gt; (import/export CSV)&lt;/li&gt;
&lt;li&gt;📈 &lt;strong&gt;Historical data&lt;/strong&gt; (time-series graphs)&lt;/li&gt;
&lt;li&gt;🌙 &lt;strong&gt;Dark mode&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🌍 &lt;strong&gt;Multi-language support&lt;/strong&gt; (i18n)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Vote on features:&lt;/strong&gt; &lt;a href="https://github.com/tosumitdhaka/trishul-snmp/issues" rel="noopener noreferrer"&gt;https://github.com/tosumitdhaka/trishul-snmp/issues&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Quick Start:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/tosumitdhaka/trishul-snmp-suite/main/install-trishul-snmp-suite.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Access:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default login:&lt;/strong&gt; &lt;code&gt;admin&lt;/code&gt; / &lt;code&gt;admin123&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Explore:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Upload a MIB file (try IF-MIB)&lt;/li&gt;
&lt;li&gt;Browse the MIB tree&lt;/li&gt;
&lt;li&gt;Walk a device (or use the simulator)&lt;/li&gt;
&lt;li&gt;Send a test trap&lt;/li&gt;
&lt;li&gt;Explore trap library&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Contributing
&lt;/h2&gt;

&lt;p&gt;Trishul-SNMP-Suite is &lt;strong&gt;100% open source&lt;/strong&gt; (MIT License).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ways to contribute:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ Star the repo&lt;/li&gt;
&lt;li&gt;🐛 Report bugs&lt;/li&gt;
&lt;li&gt;💡 Suggest features&lt;/li&gt;
&lt;li&gt;🔧 Submit PRs&lt;/li&gt;
&lt;li&gt;📝 Write tutorials&lt;/li&gt;
&lt;li&gt;💰 Sponsor development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/tosumitdhaka/trishul-snmp-suite" rel="noopener noreferrer"&gt;https://github.com/tosumitdhaka/trishul-snmp-suite&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Building Trishul-SNMP-Suite taught me:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Modern web tech can revitalize old protocols&lt;/strong&gt; - SNMP is from 1988, but a good UI makes it accessible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open source is about community, not just code&lt;/strong&gt; - Documentation, support, and engagement matter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Good UX matters, even for network tools&lt;/strong&gt; - Engineers appreciate beautiful, intuitive interfaces too&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start small, iterate fast&lt;/strong&gt; - MVP → feedback → features users actually want&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you work with SNMP, give it a try. If you find it useful, star the repo and share it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions? Comments?&lt;/strong&gt; Drop them below or open a GitHub Discussion.&lt;/p&gt;




&lt;h2&gt;
  
  
  About the Author
&lt;/h2&gt;

&lt;p&gt;I'm &lt;strong&gt;Sumit Dhaka&lt;/strong&gt;, a devops &amp;amp; integration engineer who loves building tools that make life easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connect with me:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🐙 GitHub: &lt;a href="https://github.com/tosumitdhaka" rel="noopener noreferrer"&gt;@tosumitdhaka&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 LinkedIn: &lt;a href="https://www.linkedin.com/in/sumit-dhaka-a5a796b3/" rel="noopener noreferrer"&gt;Sumit Dhaka&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📧 Email: &lt;a href="mailto:sumitdhaka@zohomail.in"&gt;sumitdhaka@zohomail.in&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Note: Its an AI generated article and may have some inconsistency.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; #snmp #networking #opensource #python #fastapi #docker #devops #webdev #mib #networkengineering&lt;/p&gt;

</description>
      <category>snmp</category>
      <category>networking</category>
      <category>opensource</category>
      <category>python</category>
    </item>
  </channel>
</rss>
