Metadata-Version: 2.4
Name: linuxfabrik-lib
Version: 8.3.0
Summary: Python 3.9+ utility library: argument parsing, output formatting, HTTP, shell, disk, SQLite/MySQL, caching, version checks, plus API clients.
Author-email: "Linuxfabrik GmbH, Zurich, Switzerland" <info@linuxfabrik.ch>
License: This is free and unencumbered software released into the public domain.
        
        Anyone is free to copy, modify, publish, use, compile, sell, or
        distribute this software, either in source code form or as a compiled
        binary, for any purpose, commercial or non-commercial, and by any
        means.
        
        In jurisdictions that recognize copyright laws, the author or authors
        of this software dedicate any and all copyright interest in the
        software to the public domain. We make this dedication for the benefit
        of the public at large and to the detriment of our heirs and
        successors. We intend this dedication to be an overt act of
        relinquishment in perpetuity of all present and future rights to this
        software under copyright law.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
        EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
        MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
        IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
        OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
        ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
        OTHER DEALINGS IN THE SOFTWARE.
        
        For more information, please refer to <https://unlicense.org/>
        
Project-URL: Homepage, https://github.com/Linuxfabrik/lib
Project-URL: Documentation, https://github.com/Linuxfabrik/lib/blob/master/README.md
Project-URL: Source, https://github.com/Linuxfabrik/lib
Project-URL: Tracker, https://github.com/Linuxfabrik/lib/issues
Project-URL: Download, https://github.com/Linuxfabrik/lib/releases
Keywords: lib,libs,monitoring,monitoring plugins,icinga,nagios
Classifier: Development Status :: 6 - Mature
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: Intended Audience :: Healthcare Industry
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Manufacturing
Classifier: Intended Audience :: Other Audience
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Telecommunications Industry
Classifier: License :: OSI Approved :: The Unlicense (Unlicense)
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System
Classifier: Topic :: System :: Monitoring
Classifier: Topic :: System :: Networking :: Monitoring
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: beautifulsoup4
Requires-Dist: httpx[http2]>=0.26
Requires-Dist: lxml
Requires-Dist: psutil
Requires-Dist: pymysql
Requires-Dist: pypsrp
Requires-Dist: pywinrm
Requires-Dist: smbprotocol
Requires-Dist: xmltodict
Dynamic: license-file

<h1 align="center">
  Linuxfabrik Python Libraries
</h1>
<p align="center">
  Python 3.9+ utility library: argument parsing, output formatting, HTTP, shell, disk, SQLite/MySQL, caching, version checks, plus API clients. Available on PyPI.
  <span>&#8226;</span>
  <b>made by <a href="https://linuxfabrik.ch/">Linuxfabrik</a></b>
</p>
<div align="center">

![GitHub Stars](https://img.shields.io/github/stars/linuxfabrik/lib)
![License](https://img.shields.io/github/license/linuxfabrik/lib)
![Version](https://img.shields.io/github/v/release/linuxfabrik/lib?sort=semver)
[![PyPI](https://img.shields.io/pypi/v/linuxfabrik-lib)](https://pypi.org/project/linuxfabrik-lib/)
![Python](https://img.shields.io/badge/Python-3.9+-3776ab)
![GitHub Issues](https://img.shields.io/github/issues/linuxfabrik/lib)
[![GitHubSponsors](https://img.shields.io/github/sponsors/Linuxfabrik?label=GitHub%20Sponsors)](https://github.com/sponsors/Linuxfabrik)
[![PayPal](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=7AW3VVX62TR4A&source=url)

</div>

<br />


# Linuxfabrik Python Libraries

A mature, production-grade Python library collection for system administration, monitoring, and infrastructure automation. It does not assume a particular consumer: any Python tool can use it, from check plugins to deployment scripts.

> If these libraries help you developing your own monitoring plugins, system tools or infrastructure automation, please give it a star.

The library requires Python 3.9+ and runs on every platform.


## Documentation

Full documentation is available at [linuxfabrik.github.io/lib](https://linuxfabrik.github.io/lib/). It is automatically built and deployed on every push to `main`.


## Installation

Add `linuxfabrik-lib` as a dependency to your project, or install it manually:

```bash
pip install --user linuxfabrik-lib
```


## Design Principles

These libraries are built with a clear set of priorities:

* **Procedural by design.** The libraries deliberately use a procedural/functional style rather than object-oriented programming. Pure functions with explicit inputs and outputs are easier to read, test, and reason about. Most consumers are short-lived, linear processes with no complex state to manage over time, where unnecessary abstraction layers would add overhead without tangible benefit.
* **Broad compatibility.** Python 3.9+ is the minimum, ensuring the libraries work on RHEL 8 and every major distribution without requiring newer runtimes.
* **Cross-platform.** Core functions behave identically on Linux, Windows, and macOS. Platform-specific code (WinRM, PowerShell, SMB) is cleanly separated.
* **Minimal dependencies.** We avoid pulling in large dependency trees. External packages are used only when the alternative would be unreliable or significantly more complex.
* **Consistent error handling.** Most functions return `(success, result)` tuples. The caller decides whether to continue or exit, the library never exits on its own. The `base.coe()` ("Continue or Exit") helper makes this pattern concise.
* **Automatic redaction.** Sensitive data (passwords, tokens, API keys) in error messages is automatically sanitized before output.
* **Nagios/Icinga conventions.** State constants, threshold evaluation, performance data formatting, and range parsing follow the [Monitoring Plugins Development Guidelines](https://www.monitoring-plugins.org/doc/guidelines.html).
* **Defensive defaults.** Functions use sensible timeouts, safe SSL settings, and locked-down defaults so that consumers work out of the box without extensive configuration.


## Library Index


### Core Utilities

| Module | Description | Key Functions |
|--------|-------------|---------------|
| **args.py** | Extends `argparse` with custom input types for monitoring thresholds, a registry of reusable `--help` texts, and reading a secret from a file instead of the command line. | `csv()`, `help()`, `int_or_none()`, `load_secret()`, `number_unit_method()` |
| **base.py** | The central module for check-style tools. Provides state evaluation, threshold comparison, performance data formatting, ASCII table output, and the `coe()` error-handling pattern. | `coe()`, `cu()`, `get_perfdata()`, `get_state()`, `get_table()`, `get_worst()`, `oao()`, `state2str()` |
| **globals.py** | Defines the four Nagios/Icinga plugin states: `STATE_OK` (0), `STATE_WARN` (1), `STATE_CRIT` (2), `STATE_UNKNOWN` (3). | -- |
| **human.py** | Converts raw numbers, byte sizes, bit rates, and durations to human-readable representations and back. Supports binary/SI prefixes and Nagios range syntax with units. | `bits2human()`, `bps2human()`, `bytes2human()`, `human2bytes()`, `human2seconds()`, `humanrange2bytes()`, `number2human()`, `seconds2human()` |
| **lftest.py** | Test harness for data-driven plugin unit tests, spinning up throwaway containers (including MySQL/MariaDB) as fixtures. | `attach_each()`, `attach_tests()`, `run()`, `run_container()`, `run_mysql_compatible_from_containerfile()`, `test()`, `test_json()` |
| **openmetrics.py** | Reads the OpenMetrics and Prometheus text exposition formats served by a `/metrics` endpoint into plain samples, and selects a metric by name and labels. | `get_samples()`, `get_value()`, `parse()` |
| **task.py** | Runs callables under a deadline that holds even where the work cannot be interrupted, each in a process of its own and all of them sharing one deadline. | `run()`, `run_each()` |
| **time.py** | Date/time conversions between UNIX epochs, ISO strings, and datetime objects, plus time-macro expansion and time differences. Timezone-aware. | `epoch2iso()`, `now()`, `timestr2datetime()`, `timestrdiff()` |
| **txt.py** | Text processing: regex compilation, substring extraction, multi-line parsing, sensitive data redaction, pluralization, shortening for display, HTML character reference resolution, and byte/text encoding conversion. | `compile_regex()`, `extract_str()`, `match_regex()`, `mltext2array()`, `pluralize()`, `shorten()`, `to_bytes()`, `to_text()`, `unescape()` |
| **version.py** | Software version parsing, comparison, and End-of-Life checking against [endoflife.date](https://endoflife.date), or against the life cycle RHEL, Debian and Ubuntu give the software they ship. | `check_eol()`, `version()`, `version2float()` |


### Data Access & Caching

| Module | Description | Key Functions |
|--------|-------------|---------------|
| **cache.py** | A simple SQLite-based key-value store with optional key expiration. Used for persisting state between runs. | `get()`, `set()` |
| **db_mysql.py** | MySQL/MariaDB client with connection management, query execution, privilege checking, and server flavor/status/variable/replication inspection. | `check_privileges()`, `connect()`, `get_all_variables()`, `get_engines()`, `get_replica_status()`, `lod2dict()`, `select()` |
| **db_sqlite.py** | Full SQLite interface: table/index creation, CRUD operations, CSV import, regex support, and per-second counter deltas for time-series data. | `connect()`, `create_index()`, `create_table()`, `cut()`, `delete()`, `insert()`, `per_second_deltas()`, `select()` |
| **logmatch.py** | Keeps log findings in an SQLite state database across runs until they age out or are acknowledged on the monitoring server, together with the read position of the log. | `acknowledge()`, `connect()`, `key()`, `pending()`, `record()`, `service_acknowledged()` |


### System & OS

| Module | Description | Key Functions |
|--------|-------------|---------------|
| **container.py** | Runs a container engine command-line client (Docker, Podman) under a deadline and tells a missing permission apart from an engine that is down or does not answer. | `get_engine_error()`, `run()` |
| **disk.py** | File I/O, directory walking, CSV/environment file parsing, block device and partition listing, and temp directory management. | `dir_exists()`, `file_exists()`, `get_real_disks()`, `get_tmpdir()`, `grep_file()`, `read_file()` |
| **distro.py** | Linux distribution detection. Returns normalized facts including distribution name, version, and Ansible-compatible `os_family`. | `get_distribution_facts()` |
| **dmidecode.py** | Parses `dmidecode` output into structured data. Extracts CPU, RAM, firmware, serial number, manufacturer, and model information. | `cpu_speed()`, `cpu_type()`, `firmware()`, `get_data()`, `manufacturer()`, `model()`, `ram()`, `serno()` |
| **endoflifedate.py** | Bundled End-of-Life data from [endoflife.date](https://endoflife.date) for offline version checks when internet access is unavailable. | -- |
| **kvm.py** | libvirt domains, storage pools and volumes via `virsh` on a read-only connection, which needs neither root nor sudo. | `get_domains()`, `get_domstats()`, `get_pool_info()`, `get_pools()`, `get_volumes()`, `virsh()` |
| **logsource.py** | Reads a log incrementally from a file, a systemd unit in the journal, or a container, and hands back a position that survives rotation and truncation. | `parse()`, `read()`, `read_many()`, `timestamp()` |
| **lvm.py** | LVM logical volumes and volume groups via `lvs` and `vgs`, including thin pools, snapshots, health status and the thin pool metadata limit. | `get_logical_volumes()`, `get_volume_groups()`, `health()`, `is_snapshot_invalid()`, `is_thin_pool()`, `metadata_limit()` |
| **lynis.py** | The machine-readable report of a Lynis security audit (`/var/log/lynis-report.dat`): hardening index, findings and suggestions, and the list of them for the plugin output. | `get_findings_msg()`, `parse_findings()`, `parse_report()` |
| **psi.py** | Linux pressure stall information (PSI) from `/proc/pressure` for CPU, I/O, IRQ and memory, with state evaluation and report output. | `get_perfdata()`, `get_states()`, `get_summary()`, `get_table()`, `is_enabled()`, `read()` |
| **psutil.py** | Wrapper around `psutil` for retrieving mounted disk partitions with device, mount point, filesystem type and mount options. Lists them from the mount table alone, so a network filesystem whose server is gone cannot hold the listing up. | `get_partitions()` |
| **restic.py** | Builds the repository and password arguments for the `restic` backup client so a privileged caller cannot make it read an arbitrary file or run an external program. | `password_file_arg()`, `repo_args()` |
| **rhelappstreams.py** | Bundled life cycle of the RHEL Application Streams, generated weekly from the data Red Hat publishes in [digital-roadmap-backend](https://github.com/RedHatInsights/digital-roadmap-backend). | -- |
| **shell.py** | Runs external commands from an argv list without a shell, guards option-style CLI values, and locates executables in `PATH`. | `safe_cli_value()`, `shell_exec()`, `which()` |
| **user.py** | Local Unix accounts: UID/GID names, the system/regular account boundary, interactive shells and the state of the shadow password. | `get_gid_name()`, `get_interactive_shells()`, `get_shadow_password()`, `get_uid_min()`, `get_uid_name()`, `password_state()` |


### Networking & HTTP

| Module | Description | Key Functions |
|--------|-------------|---------------|
| **feedparser.py** | Parses Atom and RSS feeds from URLs using BeautifulSoup. | `parse()` |
| **mail.py** | Sends email over SMTP, with an optional HTML body alongside the plain-text one and inline images referenced by Content-ID. Authenticates when a password is given. | `send()` |
| **net.py** | Low-level networking: TCP/UDP/TLS and Unix domain sockets, public IP lookup, subnet enumeration, netmask conversion, and hostname validation. | `cidr_to_hosts()`, `fetch()`, `fetch_socket()`, `get_public_ip()`, `get_subnet_hosts()`, `ip_to_cidr()` |
| **ssh.py** | Runs commands and copies files over SSH by building shell-free `ssh`/`scp`/`rsync` argument lists. | `build_options()`, `rsync()`, `run()`, `scp()`, `target()` |
| **url.py** | HTTP/1.x and HTTP/2 client (httpx) for HTML, JSON, or raw data. Supports GET/POST, Basic/Digest authentication, TLS version pinning, proxy control, and connection telemetry. | `fetch()`, `fetch_json()`, `get_latest_version_from_github()`, `split_basic_auth()`, `strip_tags()` |


### Windows Integration

| Module | Description | Key Functions |
|--------|-------------|---------------|
| **powershell.py** | Executes PowerShell commands locally (on Windows hosts). | `run_ps()` |
| **smb.py** | Native SMB/CIFS file access: list, glob, and open files on remote shares with encryption support. | `glob()`, `open_file()` |
| **winrm.py** | Executes commands and PowerShell scripts on remote Windows hosts via WinRM/PSRP, preferring pypsrp with a pywinrm fallback. | `run_cmd()`, `run_ps()` |


### API Integrations

| Module | Description | Key Functions |
|--------|-------------|---------------|
| **bexio.py** | [Bexio](https://www.bexio.com/) business software REST API (contacts, invoices, projects, items, timesheets, and more). | `call_api()`, `fetch_accounts()`, `fetch_contacts()`, `fetch_invoices()`, `fetch_projects()`, `get_all()` |
| **grassfish.py** | [Grassfish](https://www.grassfish.com/) digital signage REST API. | `fetch_json()`, `set_player_defaults()`, `set_screen_defaults()` |
| **huawei_dorado.py** | Huawei [OceanStor Dorado](https://www.huawei.com/) storage DeviceManager REST API: session handling with device ID discovery, paged list walks, current performance counters, sector-to-byte capacity conversion, and the numeric status, model and hardware codes it reports. | `as_code()`, `assert_ok()`, `field()`, `get_all_data()`, `get_data()`, `get_health_status()`, `get_health_status_state()`, `get_performance()`, `get_running_status()`, `get_running_status_state()`, `get_uuid()`, `sectors2bytes()` |
| **huawei_pacific.py** | Huawei [OceanStor Pacific](https://www.huawei.com/) storage REST API, including the older endpoint generation below `/dsware/service/`, the batch performance interface, and the status codes it reports as numbers and as strings. | `as_code()`, `assert_ok()`, `get_all_data()`, `get_data()`, `get_disk_status()`, `get_disk_status_state()`, `get_node_names_by_ip()`, `get_performance()`, `get_pool_status()`, `get_pool_status_state()`, `get_result_code()` |
| **icinga.py** | [Icinga2](https://icinga.com/) REST API client for querying a service, building an Icinga Web 2 URL and rendering a notification mail. | `api_post()`, `build_icingaweb2_url()`, `get_service()`, `render_notification_mail()` |
| **infomaniak.py** | [Infomaniak](https://www.infomaniak.com/) Swiss Backup REST API for events, backup products, and slots. | `get_events()`, `get_swiss_backup_products()`, `get_swiss_backup_slots()` |
| **jitsi.py** | [Jitsi Meet](https://jitsi.org/) server statistics endpoint, with optional HTTP Basic auth. | `get_data()` |
| **keycloak.py** | [Keycloak](https://www.keycloak.org/) identity provider with OIDC discovery, admin-token retrieval, and Admin REST API access. | `discover_oidc_endpoints()`, `get_data()`, `obtain_admin_token()` |
| **librenms.py** | [LibreNMS](https://www.librenms.org/) monitoring API, mapping its alert states to Nagios states. | `get_data()`, `get_state()` |
| **nextcloud.py** | [Nextcloud](https://nextcloud.com/) `occ` command execution as the `config.php` owner, parsing JSON or text output. | `run_occ()` |
| **nodebb.py** | [NodeBB](https://nodebb.org/) forum API, using a Bearer user token. | `get_data()` |
| **openstack.py** | [OpenStack](https://www.openstack.org/) Identity v3 authentication from an rc file, with the token reused across runs, and access to the service REST APIs. | `connect()`, `fetch()`, `fetch_json()` |
| **qts.py** | QNAP [QTS](https://www.qnap.com/) NAS API with session authentication. | `get_auth_sid()` |
| **redfish.py** | [Redfish](https://www.dmtf.org/standards/redfish) BMC API for chassis, systems, storage, managers, and sensors, deriving Nagios states and perfdata. | `get_auth_header()`, `get_perfdata()`, `get_state()`, `get_systems()` |
| **rocket.py** | [Rocket.Chat](https://www.rocket.chat/) REST API for login, room/group history, statistics, and incoming webhooks. | `get_groups_history()`, `get_rooms_get()`, `get_stats()`, `get_token()`, `send2webhook()` |
| **uptimerobot.py** | [UptimeRobot](https://uptimerobot.com/) API for monitors, alert contacts, maintenance windows, and status pages. | `delete_monitor()`, `edit_monitor()`, `get_account_details()`, `get_alert_contacts()`, `get_monitors()`, `get_mwindows()`, `get_psps()`, `new_monitor()` |
| **veeam.py** | [Veeam](https://www.veeam.com/) Backup & Replication Enterprise Manager REST API. | `get_token()` |
| **wildfly.py** | [WildFly/JBoss](https://www.wildfly.org/) management API with digest auth (standalone and domain mode). | `get_data()` |
| **wordpress.py** | [WordPress](https://wordpress.org/) installation read straight from the filesystem: core version, installed plugins and themes, the configured site URL, and any file header field. Needs no database, no HTTP request and no `wp-cli`. | `get_header_value()`, `get_plugins()`, `get_site_url()`, `get_themes()`, `get_version()`, `is_installation()` |


## Usage Example

A typical check-style tool using these libraries:

```python
import argparse

import lib.args
import lib.base
import lib.url


def main():
    parser = argparse.ArgumentParser(description='Checks the usage reported by an API.')
    parser.add_argument('--url', required=True, help=lib.args.help('--url'))
    parser.add_argument(
        '--warning',
        type=float,
        default=80,
        help=lib.args.help('--warning') + ' Default: %(default)s',
    )
    parser.add_argument(
        '--critical',
        type=float,
        default=90,
        help=lib.args.help('--critical') + ' Default: %(default)s',
    )
    args = parser.parse_args()

    # Fetch data (coe = "Continue or Exit")
    result = lib.base.coe(lib.url.fetch_json(args.url))

    # Evaluate thresholds
    state = lib.base.get_state(result['usage'], args.warning, args.critical)
    perfdata = lib.base.get_perfdata(
        'usage', result['usage'], '%', args.warning, args.critical, 0, 100
    )

    # Output and exit
    lib.base.oao(f'Usage is {result["usage"]}%', state, perfdata)


if __name__ == '__main__':
    main()
```


## Tips & Tricks

Count the function calls to any "lib" library in your project and sort by frequency:

```bash
grep -rhoP '\Wlib\.[a-zA-Z0-9_\.]+' * | sed 's/^[^a-zA-Z0-9]*//' | sort | uniq -c | sort -nr
```
