Metadata-Version: 2.4
Name: usb-inspector
Version: 1.1.0
Summary: A cross-platform tool to monitor and inspect USB devices connected to the host system.
Project-URL: Repository, https://bitbucket.org/xstudios/usb-inspector.git
Project-URL: Issues, https://bitbucket.org/xstudios/usb-inspector/issues
Project-URL: Changelog, https://bitbucket.org/xstudios/usb-inspector/blob/master/HISTORY.md
Author-email: Tim Santor <tsantor@xstudios.com>
License-File: AUTHORS.md
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.11
Requires-Dist: chardet>=5.2.0
Requires-Dist: click>=8.3.0
Requires-Dist: numpy==2.3.3
Requires-Dist: pandas==2.3.3
Requires-Dist: platformdirs>=4.5.0
Requires-Dist: pyusb>=1.3.1
Requires-Dist: requests>=2.32.5
Requires-Dist: tabulate>=0.9.0
Description-Content-Type: text/markdown

# USB Inspector

![Coverage](https://img.shields.io/badge/coverage-92.05%25-brightgreen)

## Overview

A simple package that leverages `pyusb` and allows you to lookup USB vendor and device IDs and get back a human readable vendor and device name.
It includes ability to manually update the USB DB without installing a new version of `usb-inspector`.

## Installation

```bash
uv add usb-inspector
# via pip
python3 -m pip install usb-inspector
```

**IMPORTANT**: On Windows ensure you have `libusb-1.0.dll` (64bit) in `C:\Windows\System32` or you will get a `NoBackendError`. You can get it from [here](https://libusb.info/).

## Example Usage

Command Line:
```bash
usb-inspector lookup --vendor-id 1A40
usb-inspector lookup --vendor-id 1A40 --device-id 0801

# To manually update the USB DB
usb-inspector delete-data
usb-inspector update-db
```

```python
import asyncio

from usb_inspector import create_usb_monitoring_service

async def main():
    service = create_usb_monitoring_service(poll_interval=1.0)
    monitor_task = asyncio.create_task(service.run())
    await asyncio.sleep(10)
    await service.stop()
    await monitor_task

asyncio.run(main())
```

## Device identity

USB Inspector uses a device's vendor/product IDs and USB serial number as its
preferred identity. When a backend cannot read a serial number temporarily, it
uses the USB bus and port path to retain the identity already associated with
that physical connection. USB addresses are not treated as stable because they
can change when a device re-enumerates.

If a device has no readable serial number and is moved to a different USB port,
it is necessarily reported as a new device.

## Issues

If you experience any issues, please create an [issue](https://bitbucket.org/xstudios/usb-inspector/issues) on Bitbucket.


## Development

To get a list of all commands with descriptions simply run `just`.

```bash
just env
just pip-install-editable
```

## Testing

```bash
just pytest
just coverage
just open-coverage
```


---

# History

All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).

## 1.1.0 (2026-08-11)

- FIXED transient USB serial-number read failures no longer create duplicate device records or spurious disconnect/connect events.
- CHANGED device monitoring now reads each serial number once per snapshot and uses the USB bus/port path to preserve an established device identity when the serial is temporarily unavailable.
- ADDED detection of a different serial number at the same USB port as a device replacement.

## 1.0.0 (2026-05-22)

**Breaking changes**

- REMOVED `USBDeviceMonitor` from the public API. Use `create_usb_monitoring_service()` instead, which returns a `USBMonitoringService` instance with the same behavior.
- REMOVED standalone free functions `lookup_usb_details`, `delete_usb_db`, `delete_data_file`, and `update_usb_db` from `usb_inspector.usb.infrastructure.repository`. Use `SQLiteUSBDetailsRepository` and `USBDatabaseMaintenanceRepository` directly.
- CHANGED public API of `usb_inspector` package now exports `USBMonitoringService`, `USBDetailsLookupPort`, and `create_usb_monitoring_service`. Importing `USBDeviceMonitor` from the top-level package will raise `ImportError`. `USBEnumeratorPort` remains importable from `usb_inspector.usb.application.ports`.

**Other changes**

- CHANGED package no longer initialises the USB database on import. Initialisation is now lazy: the database is created on the first call to `SQLiteUSBDetailsRepository.lookup()` if it does not already exist.
- CHANGED `usb_inspector.usb` package no longer re-exports `USBMonitoringService`; import from `usb_inspector` or `usb_inspector.usb.application.service` directly.
- CHANGED `usb_inspector.usb.infrastructure` package now exports only `create_usb_monitoring_service`; concrete repository classes remain importable from their module.

## 0.3.1 (2026-04-21)
- CHANGED updated build backend and release tooling configuration.
- CHANGED refreshed Justfile workflows for environment, testing, and release checks.
- CHANGED updated packaging/verification helper scripts and dependency lock maintenance.
- CHANGED updated pre-commit toolchain versions.

## 0.3.0 (2026-03-13)
- CHANGED refactored package internals to a layered DDD structure under `usb_inspector.usb` (domain/application/infrastructure/interface).
- CHANGED internal legacy modules `db.py`, `update.py`, and `cli.py` were removed; CLI entry point now resolves to `usb_inspector.usb.interface.router:cli`.
- CHANGED `usb_inspector.monitor` remains available as a compatibility shim for `USBDeviceMonitor`.
- FIXED circular import issues in package initialization/import flow.
- ADDED layered test coverage for application and infrastructure modules plus import regression coverage.

## 0.2.2 (2025-12-04)
- ADDED tox and more test coverage

## 0.2.1 (2025-11-21)
- ADDED `port` to the device info
- CHANGED cleaned up logging on connect/disconnect descriptions

## 0.2.0 (2025-11-21)
- FIXED Connecting/Disconnecting the same physical device to the same port now correctly identifies the device as the same device on Windows/Linux.

## 0.1.9 (2025-11-21)
- FIXED Cached sql db lookup so it occurs only once.

## 0.1.8 (2025-11-20)
- FIXED turned default packaged logging to `ERROR`. Was `INFO`...Sorry!

## 0.1.7 (2025-11-13)
- FIXED `is_connected` bug introduced in last patch.
- ADDED improved tracking of devices allowing multiple of the same vendor/device ID to be connected.

## 0.1.6 (2025-11-13)
- FIXED `last_seen` timestamp for each device, only updates when connected/disonnected.

## 0.1.5 (2025-11-05)
- Locked `pandas` to version 2.3.3 for Raspberry Pi compatability (it pulls the pre-built wheel from piwheels.org)

## 0.1.4 (2025-11-05)
- Added `last_seen` timestamp for each device.

## 0.1.4 (2025-10-31)

- `update-db` cli command only adds new Vendors and Devices to the existing DB rather than requiring deletion and recreation of the DB.
- Track which devices are connected/disconnected.

## 0.1.2 (2025-10-30)

- Fix lookup error

## 0.1.1 (2025-10-30)

- Added `start` as an alias for `monitor`.

## 0.1.0 (2025-10-30)

- First release
