# PySMI library

The MibCompiler object is the top-most interface to PySMI library features. It holds together the otherwise isolated pieces of the compiler infrastructure and manages the workflow of ASN.1 MIB transformation.

This example showcases some of its features:

    from pysmi.reader import HttpReader
    from pysmi.searcher import StubSearcher
    from pysmi.writer import CallbackWriter
    from pysmi.parser import SmiStarParser
    from pysmi.codegen import JsonCodeGen
    from pysmi.compiler import MibCompiler

    inputMibs = ['IF-MIB', 'IP-MIB']

    httpSources = [('mibs.snmplabs.com', 80, '/asn1/@mib@')]

    # store compiled MIBs by calling this function
    def store_mibs(mibName, jsonDoc, cbCtx):
        print('# MIB module %s' % mibName)
        print(jsonDoc)

    mibCompiler = MibCompiler(
        SmiStarParser(), JsonCodeGen(), CallbackWriter(store_mibs)
    )

    # pull ASN.1 MIBs over HTTP
    mibCompiler.addSources(*[HttpReader(*x) for x in httpSources])

    # never recompile MIBs with ASN.1 MACROs
    mibCompiler.addSearchers(StubSearcher(*JsonCodeGen.baseMibs))

    status = mibCompiler.compile(*inputMibs)

    print(status)

- MIB compiler
  - `MibCompiler`
- Compilation status
  - `MibStatus`

## MIB sources

PySMI offers a handful of distinct transport mechanisms for fetching MIBs by name from specific locations. In all cases MIB module name to file name match may not be exact – some name fuzzying can be performed to mitigate possible changes to MIB file name.

- Local file reader
  - `FileReader`
- ZIP archive reader
  - `ZipReader`
- HTTP reader
  - `HttpReader`
- FTP reader
  - `FtpReader`
- Callback reader
  - `CallbackReader`

## Conditional compilation

There are cases when MIB transformation may or must not be performed. Such cases include:

- foundation MIBs containing manually implemented pieces or ASN.1 MACRO’s

- obsolete MIBs fully reimplemented within modern MIBs

- already transformed MIBs

MibCompiler expects user to supply a searcher object that would allow or skip MIB transformation for particular name based on whatever reason it is aware of.

In general, searcher logic is specific to target format. At the time being, only pysnmp code generation backend requires such filtering.

- Python files searcher
  - `PyFileSearcher`
- Search Python packages
  - `PyPackageSearcher`
- Unconditionally ignore MIBs
  - `StubSearcher`

## Parser configuration

MIBs may be written in one of the two major SMI language versions (v1 and v2). Some MIBs may contain typical errors.

PySMI offers a way to customize the parser to consume either of the major SMI grammars as well as to recover from well-known errors in MIB files.

- SMI parser
  - `parserFactory()`
- SMI language dialects

## Code generators

Once ASN.1 MIB is parsed up, AST is passed to a code generator which turns AST into desired representation of the MIB.

- JSON document generator
  - `JsonCodeGen`
- PySNMP MIB generator
  - `PySnmpCodeGen`
- Code generation stub
  - `NullCodeGen`

## Borrow pre-compiled MIBs

Some MIBs in circulation appear broken beyond automatic repair. To handle such cases PySMI introduces the MIB borrowing functionality. When MibCompiler gives up compiling a MIB, it can try to go out and take a copy of already transformed MIB to complete the request successfully.

- Any file borrower
  - `AnyFileBorrower`
- Python file borrower
  - `PyFileBorrower`

## Write compiled MIBs

Successfully transformed MIB modules’ contents will be passed to writer object given to MibCompiler on instantiation.

- File writer
  - `FileWriter`
- Python file writer
  - `PyFileWriter`
- Callback writer
  - `CallbackWriter`

## Examples

The following examples focus on various feature of the PySMI library.

- Compile MIBs into JSON
- Compile MIBs from web
- Compile SMIv1/v2 MIBs
- Compile SMIv2 MIBs
- Borrow pysnmp MIBs on failure
- Always borrow pysnmp MIBs

In case of any troubles or confusion, try enabling PySMI debugging and watch the output:

    from pysmi import debug

    debug.setLogger(debug.Debug('all'))