Metadata-Version: 2.4
Name: dmiparser
Version: 7.1
Summary: This parses dmidecode output to Python objects. The Python module supports multiple output formats (JSON, JSONC, YAML, XML) via the format parameter, and provides CLI tools with the same capabilities
Home-page: https://github.com/Arondight/python-dmiparser
Download-URL: https://github.com/Arondight/python-dmiparser/tags
Author: Qin Fandong
Author-email: shell_way@foxmail.com
License: MIT
Platform: Any
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: download-url
Dynamic: license-file

# python-dmiparser

> **Breaking Changes in 7.0:**
>
> 1. The Python API changes: `DmiParser` and `DmiDecoder` gain `pretty` and `format` parameters, and `DmiParser` gains a `.data` property. The old `sort_keys=True, indent=2` kwargs pattern is replaced by `pretty=True`.
> 2. The CLI changes: `--format` (`-f`) now takes a value (`json`, `jsonc`, `yaml`) instead of being a boolean pretty-print toggle; use `--pretty` (`-p`) for human-friendly output.
>
> See [Migration Guide](#migration-from-6x-to-7x) below.

## About

This parses `dmidecode` output to Python objects. The Python module supports multiple output formats (JSON, JSONC, YAML, XML) via the `format` parameter, and provides CLI tools with the same capabilities.

## Installation

### PyPI

```shell
pip3 install -U dmiparser
```

### RPM

```shell
git clone https://github.com/Arondight/python-dmiparser.git
cd ./python-dmiparser/
python3 ./setup.py bdist --format=rpm
sudo dnf install ./dist/dmiparser-*.noarch.rpm
```

> Tip: Requires the `rpm-build` package in your Linux distribution.

## Usage

### Python 3 script

#### DmiParser

This accepts a `str` (with the output of `dmidecode`) as argument and converts it to formatted text. The `format` parameter selects output format (`json`, `jsonc`, `yaml`, `xml`), `pretty` enables human-friendly output, and the `.data` property provides parsed Python objects.

```python
#!/usr/bin/env python3
from dmiparser import DmiParser
from functools import partial


def report(*args: str) -> None:
    """report texts with format

    @param args: text string
    """
    br = lambda e: print("-" * e)
    brn = partial(br, 80)

    brn()

    for e in args:
        print(e)
        brn()


if "__main__" == __name__:
    text = (
        "# dmidecode 3.6\n"
        "Getting SMBIOS data from sysfs.\n"
        "SMBIOS 3.7.0 present.\n"
        "\n"
        "Handle 0x0000, DMI type 0, 26 bytes\n"
        "Platform Firmware Information\n"
        "\tVendor: American Megatrends International, LLC.\n"
        "\tVersion: 3A09.QCT001\n"
        "\tRelease Date: 11/14/2024\n"
        "\tAddress: 0xF0000\n"
        "\tRuntime Size: 64 KiB\n"
        "\tROM Size: 64 MiB\n"
        "\tCharacteristics:\n"
        "\t\tPCI is supported\n"
        "\t\tFirmware is upgradeable\n"
        "\t\tFirmware shadowing is allowed\n"
        "\t\tBoot from CD is supported\n"
        "\t\tSelectable boot is supported\n"
        "\t\tFirmware ROM is socketed\n"
        "\t\tEDD is supported\n"
        "\t\tACPI is supported\n"
        "\t\tBIOS boot specification is supported\n"
        "\t\tTargeted content distribution is supported\n"
        "\t\tUEFI is supported\n"
        "\tPlatform Firmware Revision: 5.35\n"
        "\tEmbedded Controller Firmware Revision: 3.9\n"
        "\n"
    )

    parser = DmiParser(text)                                # compact JSON
    # parser = DmiParser(text, pretty=True)                 # pretty JSON
    # parser = DmiParser(text, format="jsonc")              # compact JSONC
    # parser = DmiParser(text, format="jsonc", pretty=True) # pretty JSONC
    # parser = DmiParser(text, format="yaml")               # compact YAML
    # parser = DmiParser(text, format="yaml", pretty=True)  # pretty YAML
    # parser = DmiParser(text, format="xml")                # compact XML
    # parser = DmiParser(text, format="xml", pretty=True)   # pretty XML

    parsedStr = str(parser)  # get str
    parsedObj = parser.data  # get parsed objects

    report(parsedStr, parsedObj)
```

#### DmiDecoder (the default wrapper)

This runs `dmidecode` and converts the output to formatted text. Supports `format` and `pretty` parameters like `DmiParser`.

```python
from dmiparser.dmidecoder import DmiDecoder
from functools import partial


def report(*args: str) -> None:
    """report texts with format

    @param args: text string
    """
    br = lambda e: print("-" * e)
    brn = partial(br, 80)

    brn()

    for e in args:
        print(e)
        brn()


def getCpuInfo(dmidecoder) -> str:
    """Get CPU information, will return text like below.

    CPU_0:
        Family: Xeon
        Version: Intel(R) Xeon(R) 6767P
        Voltage: 1.8 V
        Speed: 2400 MHz/3900 MHz
        Status: Populated, Enabled
        Core: 64/64
        Thread: 128
    CPU_1:
        Family: Xeon
        Version: Intel(R) Xeon(R) 6767P
        Voltage: 1.8 V
        Speed: 2400 MHz/3900 MHz
        Status: Populated, Enabled
        Core: 64/64
        Thread: 128

    @param dmidecoder: DmiDecoder object
    @return: text of CPU information
    """
    text = ""

    for sid, name in dmidecoder.sections:
        def getFirst(*args):
            vals = dmidecoder.getProp(*args, id=sid, name=name)
            return vals[0] if len(vals) > 0 else None

        text += "{}:\n".format(getFirst("Socket Designation"))
        text += "\tFamily: {}\n".format(getFirst("Family"))
        text += "\tVersion: {}\n".format(getFirst("Version"))
        text += "\tVoltage: {}\n".format(getFirst("Voltage"))
        text += "\tSpeed: {}/{}\n".format(getFirst("Current Speed"), getFirst("Max Speed"))
        text += "\tStatus: {}\n".format(getFirst("Status"))
        text += "\tCore: {}/{}\n".format(getFirst("Core Enabled"), getFirst("Core Count"))
        text += "\tThread: {}\n".format(getFirst("Thread Count"))

    return text


if "__main__" == __name__:
    dmidecoder4 = DmiDecoder("-t 4")                                # compact JSON
    # dmidecoder4 = DmiDecoder("-t 4", pretty=True)                 # pretty JSON
    # dmidecoder4 = DmiDecoder("-t 4", format="jsonc")              # compact JSONC
    # dmidecoder4 = DmiDecoder("-t 4", format="jsonc", pretty=True) # pretty JSONC
    # dmidecoder4 = DmiDecoder("-t 4", format="yaml")               # compact YAML
    # dmidecoder4 = DmiDecoder("-t 4", format="yaml", pretty=True)  # pretty YAML
    # dmidecoder4 = DmiDecoder("-t 4", format="xml")                # compact XML
    # dmidecoder4 = DmiDecoder("-t 4", format="xml", pretty=True)   # pretty XML

    report(dmidecoder4.text, str(dmidecoder4.data), getCpuInfo(dmidecoder4))
```

> Tip: Superuser permissions are required here to run `dmidecode`.

### Executable command

#### dmiparser

This reads `dmidecode` output from stdin and outputs in multiple formats (JSON, JSONC, YAML, XML).

```shell
sudo dmidecode | dmiparser              # compact JSON
sudo dmidecode | dmiparser -p           # pretty JSON
sudo dmidecode | dmiparser -f jsonc     # compact JSONC
sudo dmidecode | dmiparser -f jsonc -p  # pretty JSONC
sudo dmidecode | dmiparser -f yaml      # compact YAML
sudo dmidecode | dmiparser -f yaml -p   # pretty YAML
sudo dmidecode | dmiparser -f xml       # compact XML
sudo dmidecode | dmiparser -f xml -p    # pretty XML
```

```shell
sudo dmidecode >/tmp/dmidecode.txt
dmiparser </tmp/dmidecode.txt
```

> Tip: you can run `dmiparser` module as a script (use `python3 -m dmiparser` instead of `dmiparser` command).

#### dmidecoder

This runs `dmidecode` and outputs in multiple formats (JSON, JSONC, YAML, XML).

```shell
sudo env "PATH=$PATH" dmidecoder                # compact JSON
sudo env "PATH=$PATH" dmidecoder -p             # pretty JSON
sudo env "PATH=$PATH" dmidecoder -f jsonc       # compact JSONC
sudo env "PATH=$PATH" dmidecoder -f jsonc -p    # pretty JSONC
sudo env "PATH=$PATH" dmidecoder -f yaml        # compact YAML
sudo env "PATH=$PATH" dmidecoder -f yaml -p     # pretty YAML
sudo env "PATH=$PATH" dmidecoder -f xml         # compact XML
sudo env "PATH=$PATH" dmidecoder -f xml -p      # pretty XML
```

> Tips:
>
> 1. `sudo` resets `PATH` via `secure_path`, so pip-installed commands like `dmidecoder` may not be found. Use `sudo env "PATH=$PATH" dmidecoder` to preserve it.
> 2. You can run `dmiparser.dmidecoder` module as a script (use `python3 -m dmiparser.dmidecoder` instead of `dmidecoder` command).

## Migration from 6.x to 7.x

In 7.0, **both the Python API and CLI introduce breaking changes**.

1. **Python API:** `DmiParser` and `DmiDecoder` gain `pretty` and `format` parameters. The old `sort_keys=True, indent=2` kwargs pattern is replaced by `pretty=True`. `DmiParser` also gains a `.data` property for direct access to parsed objects.
2. **CLI:** The `-f` / `--format` flag was repurposed: it now takes a format value (`json`, `jsonc`, `yaml`) instead of being a pretty-print toggle. The old pretty-print behavior moved to a new `-p` / `--pretty` flag.

**Parameter changes:**

| Type | 6.x                        | 7.x               | What changed                                 |
| ---- | -------------------------- | ----------------- | -------------------------------------------- |
| API  | `sort_keys=True, indent=2` | `pretty=True`     | Pretty-print via parameter instead of kwargs |
| CLI  | `-f` / `--format`          | `-p` / `--pretty` | Pretty-print is now a separate flag          |

**Python API migration examples:**

| 6.x                                            | 7.x                               |
| ---------------------------------------------- | --------------------------------- |
| `DmiParser(text, sort_keys=True, indent=2)`    | `DmiParser(text, pretty=True)`    |
| `DmiDecoder("-t 4", sort_keys=True, indent=2)` | `DmiDecoder("-t 4", pretty=True)` |
| `json.loads(str(parser))`                      | `parser.data`                     |

**Command migration examples:**

| 6.x                                      | 7.x                                      |
| ---------------------------------------- | ---------------------------------------- |
| `dmiparser --format`                     | `dmiparser --pretty`                     |
| `dmidecoder --format`                    | `dmidecoder --pretty`                    |
| `dmidecoder --arguments "-t 4" --format` | `dmidecoder --arguments "-t 4" --pretty` |

## Development

### Test

```shell
tox
```

### Format

```shell
black -l 120 ./dmiparser/ ./tests/
```

## License

[MIT LICENSE](https://github.com/Arondight/python-dmiparser/blob/master/LICENSE).
