Metadata-Version: 2.4
Name: dmi-reader
Version: 1.0.0
Summary: Cross-platform DMI hardware identifier reader without root/admin privileges
Author-email: saiconfirst <247169576+saiconfirst@users.noreply.github.com>
License: Non-Commercial
Project-URL: Homepage, https://github.com/saiconfirst/dmi_reader
Project-URL: Repository, https://github.com/saiconfirst/dmi_reader
Project-URL: Issues, https://github.com/saiconfirst/dmi_reader/issues
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Hardware
Classifier: Topic :: Security
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: wmi>=1.5.1; sys_platform == "win32"
Requires-Dist: pywin32>=227; sys_platform == "win32"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: flake8>=5.0.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Dynamic: license-file

# `dmi-reader` — Cross-Platform DMI Hardware Identifier Reader

<div align="center">

[![License: Non-Commercial](https://img.shields.io/badge/License-Non--Commercial-red.svg)](LICENSE)
[![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)
[![PyPI](https://img.shields.io/pypi/v/dmi-reader.svg)](https://pypi.org/project/dmi-reader/)
![GitHub Repo stars](https://img.shields.io/github/stars/saiconfirst/dmi_reader?style=social)
![PyPI - Downloads](https://img.shields.io/pypi/dm/dmi-reader?label=PyPI%20downloads)
![GitHub last commit](https://img.shields.io/github/last-commit/saiconfirst/dmi_reader)
![GitHub issues](https://img.shields.io/github/issues/saiconfirst/dmi_reader)

Securely retrieve unique hardware identifiers (DMI, UUID, serial numbers) across Linux, Windows, and macOS — **without requiring root/admin privileges**.

</div>

---

## 🚀 Features

- ✅ **Cross-Platform**: Works on Linux, Windows, macOS
- ✅ **No Root/Admin Required**: Reads DMI safely without elevated permissions
- ✅ **Thread-Safe Caching**: Efficient, avoids repeated system calls
- ✅ **Container-Aware**: Automatically detects Docker, Podman, etc.
- ✅ **Graceful Degradation**: Handles missing/wrong DMI gracefully
- ✅ **Fallback Support**: Uses `machine-id`, `hostname` when DMI unavailable
- ✅ **Production-Ready**: Robust error handling, logging, type hints

---

## 📦 Installation

```bash
pip install -r requirements.txt
```

### Dependencies

- On **Windows**: automatically installs `wmi` and `pywin32`
- On **Linux/macOS**: no additional dependencies needed

---

## 💡 Usage

### Basic usage

```python
from dmi_reader import get_dmi_info

# Get all available DMI information (with fallback)
info = get_dmi_info(include_fallback=True)
print(info)
# Example output:
# {
#   'system_uuid': '123e4567-e89b-12d3-a456-426614174000',
#   'board_serial': 'ABC123456',
#   'chassis_serial': 'CHS789012',
#   'product_name': 'VMware Virtual Platform',
#   'manufacturer': 'VMware, Inc.'
# }

# Strict mode – only DMI data, no fallback
info = get_dmi_info(include_fallback=False)
```

### Advanced: caching and threading

The library is thread‑safe and caches results automatically. If you need fresh data on every call, use `force_refresh`:

```python
from dmi_reader import get_dmi_info

# Force a fresh read (bypass cache)
info = get_dmi_info(force_refresh=True)
```

### Integration with logging

```python
import logging
from dmi_reader import get_dmi_info

logging.basicConfig(level=logging.DEBUG)
info = get_dmi_info()
# The library logs at DEBUG level, helpful for debugging
```

### Use case: device fingerprinting

```python
from dmi_reader import get_dmi_info
import hashlib
import json

def device_fingerprint() -> str:
    info = get_dmi_info(include_fallback=True)
    # Sort keys for consistent hashing
    data = json.dumps(info, sort_keys=True).encode()
    return hashlib.sha256(data).hexdigest()[:16]

print(f"Device fingerprint: {device_fingerprint()}")
```

### Use in web applications (FastAPI example)

```python
from fastapi import FastAPI
from dmi_reader import get_dmi_info

app = FastAPI()

@app.get("/system/info")
async def system_info():
    return get_dmi_info(include_fallback=True)
```

# Or python test.py
---

## 🤔 Why dmi‑reader?

| Feature | dmi‑reader | `dmidecode` (Linux) | `wmic` (Windows) | `system_profiler` (macOS) |
|---------|------------|---------------------|------------------|---------------------------|
| **No root/admin** | ✅ Yes | ❌ Requires `sudo` | ⚠️ May need admin | ✅ Yes |
| **Cross‑platform** | ✅ Linux, Windows, macOS | ❌ Linux only | ❌ Windows only | ❌ macOS only |
| **Python API** | ✅ Clean, typed | ❌ Shell parsing | ❌ Shell parsing | ❌ Shell parsing |
| **Container‑aware** | ✅ Skips in containers | ❌ May fail | ❌ N/A | ❌ N/A |
| **Thread‑safe** | ✅ With caching | ❌ Process‑based | ❌ Process‑based | ❌ Process‑based |
| **Graceful fallback** | ✅ Uses machine‑id, hostname | ❌ Fails | ❌ Fails | ❌ Fails |

**dmi‑reader** is the only library that provides a **uniform, secure, and dependency‑free** way to read hardware identifiers across all major platforms.

---

## 🛠️ Supported Platforms

| Platform | Method | Requires Root/Admin |
|----------|--------|--------------------|
| Linux    | `/sys/class/dmi/id/` | No |
| Windows  | WMI (with timeout) | No |
| macOS    | `system_profiler` | No |

---

## ⚠️ License & Commercial Use

This software is **free for personal and non-commercial use only**.

**Any commercial use** — including but not limited to:
- Integration into commercial products
- Use in business operations
- Distribution as part of paid services
- Use in corporate environments

**requires explicit written permission from the author.**

To request a commercial license, contact:  
**Telegram**: [@saicon001](https://t.me/saicon001)

---

## 🧪 Testing

```bash
# Clone the repository
git clone https://github.com/saiconfirst/dmi_reader.git
cd dmi-reader

# Install dependencies
pip install -r requirements.txt

# Run test script
python test.py
```

---

## 🤝 Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

---
## ❓ FAQ

### Is this library safe to use in production?
Yes. It has zero external dependencies (except `wmi`/`pywin32` on Windows, which are auto‑installed), handles errors gracefully, and is thread‑safe.

### Does it work inside Docker containers?
Yes. It automatically detects container environments (Docker, Podman, etc.) and skips DMI reading (which would fail). Fallback identifiers (`machine‑id`, `hostname`) are used instead.

### Can I use this for license key generation?
Yes, many developers use hardware identifiers as part of license validation. However, note that DMI data can be spoofed in virtualized environments. Use it as **one factor** in a multi‑factor validation scheme.

### How does it compare to reading `/sys/class/dmi/id` directly?
Reading `/sys/class/dmi/id` requires root on some systems; dmi‑reader uses the same path but **never requires elevated privileges**. It also adds caching, container detection, and fallback mechanisms.

### What happens if DMI data is missing or invalid?
The library falls back to `machine‑id` (Linux), `hostname` (Windows/macOS), or a combination. You can control this with `include_fallback=False` to get only DMI data.

### Is there a performance overhead?
The first call may take a few milliseconds (WMI on Windows is slower). Subsequent calls use an in‑memory cache, making them microseconds fast.

### Can I contribute?
Absolutely! See [Contributing](#-contributing). We welcome bug reports, feature requests, and pull requests.

---
## 💖 Support

If you find this project useful, consider supporting its development:

- **Commercial licensing** for business use: contact [@saicon001 on Telegram](https://t.me/saicon001)
- **Sponsor** the developer via [GitHub Sponsors](https://github.com/sponsors/saiconfirst) (coming soon)
- **Star** the repository to show your appreciation

---

## 📜 License

This project is licensed under a Non-Commercial License. Commercial use requires explicit written permission from the author. See the [LICENSE](LICENSE) file for full terms.

---

<div align="center">

Made with ❤️ by [saiconfirst](https://github.com/saiconfirst)

For commercial licensing inquiries: **[@saicon001](https://t.me/saicon001)**

</div>
