system-parse-lib 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
@@ -0,0 +1,171 @@
1
+ import os, subprocess, getpass, socket
2
+ from dataclasses import dataclass, asdict
3
+ from functools import cache
4
+
5
+ PCI_DEVICES = "/sys/bus/pci/devices"
6
+ PCI_IDS_PATHS = (
7
+ "/usr/share/hwdata/pci.ids",
8
+ "/usr/share/misc/pci.ids",
9
+ "/usr/share/pci.ids",
10
+ )
11
+ VENDORS = {"10de": "NVIDIA", "1002": "AMD", "8086": "Intel"}
12
+
13
+ @dataclass
14
+ class GPU:
15
+ vendor: str
16
+ model: str
17
+ driver: str | None = None
18
+
19
+ def _read_sysfs(path):
20
+ try:
21
+ with open(path) as f:
22
+ return f.read().strip()
23
+ except OSError:
24
+ return None
25
+
26
+ @cache
27
+ def _load_pci_ids():
28
+ """Returns {(vendor_id, device_id): name}"""
29
+ names = {}
30
+ for path in PCI_IDS_PATHS:
31
+ try:
32
+ f = open(path, encoding="utf-8", errors="replace")
33
+ except OSError:
34
+ continue
35
+ with f:
36
+ vendor = None
37
+ for line in f:
38
+ if line.startswith("#") or not line.strip():
39
+ continue
40
+ if line.startswith("C "):
41
+ break
42
+ if line.startswith("\t\t"):
43
+ continue
44
+ if line.startswith("\t"):
45
+ dev_id, _, name = line.strip().partition(" ")
46
+ if vendor:
47
+ names[(vendor, dev_id)] = name
48
+ else:
49
+ vendor = line.split()[0]
50
+ break
51
+ return names
52
+
53
+ class Main():
54
+ def __init__(self):
55
+ def get_distro_info():
56
+ if not os.path.exists('/etc/os-release'):
57
+ return None
58
+
59
+ info = {}
60
+
61
+ with open('/etc/os-release') as f:
62
+ for line in f:
63
+ if '=' in line:
64
+ key, value = line.strip().split('=', 1)
65
+ info[key] = value
66
+ return info
67
+ self.distro_info = get_distro_info()
68
+
69
+ def get_distro_id(self):
70
+ if not self.distro_info:
71
+ return None
72
+ return self.distro_info.get('ID', '').strip('"')
73
+
74
+ def get_username(self):
75
+ username = getpass.getuser()
76
+ return username
77
+
78
+ def get_kernel_version(self):
79
+ kernel_version = os.uname().release
80
+ return kernel_version
81
+
82
+ def get_uptime_seconds(self):
83
+ try:
84
+ with open("/proc/uptime") as f:
85
+ return int(float(f.read().split()[0]))
86
+ except (OSError, ValueError, IndexError):
87
+ return None
88
+
89
+ def get_pretty_uptime(self):
90
+ seconds = self.get_uptime_seconds()
91
+ if seconds is None:
92
+ return None
93
+
94
+ days, rem = divmod(seconds, 86400)
95
+ hours, rem = divmod(rem, 3600)
96
+ minutes = rem // 60
97
+
98
+ parts = []
99
+ if days:
100
+ parts.append(f"{days} day{'s' if days != 1 else ''}")
101
+ if hours:
102
+ parts.append(f"{hours} hour{'s' if hours != 1 else ''}")
103
+ if minutes or not parts:
104
+ parts.append(f"{minutes} minute{'s' if minutes != 1 else ''}")
105
+ return "up " + ", ".join(parts)
106
+
107
+ def get_session_type(self):
108
+ session_type = os.getenv('XDG_SESSION_TYPE')
109
+ if session_type:
110
+ return session_type
111
+ else:
112
+ return "Could not retrieve session type."
113
+
114
+ def get_hostname(self):
115
+ hostname = socket.gethostname()
116
+ return hostname
117
+
118
+ def get_pretty_name(self):
119
+ if not self.distro_info:
120
+ return None
121
+ return self.distro_info.get('PRETTY_NAME', '').strip('"')
122
+
123
+ def get_de(self):
124
+ desktop = os.environ.get("XDG_CURRENT_DESKTOP") or os.environ.get("DESKTOP_SESSION")
125
+ if desktop:
126
+ return desktop
127
+ return None
128
+
129
+ def get_cpu(self):
130
+ cpu = ""
131
+ try:
132
+ with open("/proc/cpuinfo", "r", encoding="utf-8") as file:
133
+ for line in file:
134
+ if "model name" in line.lower():
135
+ cpu = line.split(":", 1)[-1].strip()
136
+ break
137
+ except FileNotFoundError:
138
+ return None
139
+ return cpu
140
+
141
+ def get_gpu(self):
142
+ gpus = []
143
+ try:
144
+ devices = sorted(os.listdir(PCI_DEVICES))
145
+ except OSError:
146
+ return gpus
147
+
148
+ ids = _load_pci_ids()
149
+
150
+ for dev in devices:
151
+ base = os.path.join(PCI_DEVICES, dev)
152
+
153
+ pci_class = _read_sysfs(base + "/class")
154
+ if not pci_class or not pci_class.startswith("0x03"):
155
+ continue
156
+
157
+ vendor_id = (_read_sysfs(base + "/vendor") or "")[2:]
158
+ device_id = (_read_sysfs(base + "/device") or "")[2:]
159
+
160
+ vendor = VENDORS.get(vendor_id, vendor_id)
161
+
162
+ name = ids.get((vendor_id, device_id), f"Device {device_id}")
163
+ model = name.split('[')[-1].split(']')[0] if '[' in name else name
164
+
165
+ driver = None
166
+ if os.path.exists(base + "/driver"):
167
+ driver = os.path.basename(os.path.realpath(base + "/driver"))
168
+
169
+ gpus.append(GPU(vendor=vendor, model=model, driver=driver))
170
+
171
+ return gpus
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.5
2
+ Name: system-parse-lib
3
+ Version: 0.0.1
4
+ Summary: A for now small python library used for getting information about the system and hardware on linux. Dependency free! (well, not really)
5
+ Project-URL: Homepage, https://github.com/black-mesa-studios/system-parse-lib
6
+ Project-URL: Issues, https://github.com/black-mesa-studios/system-parse-lib/issues/
7
+ Author-email: Artem Ivashyn <artem4ik15082013@gmail.com>
8
+ License-Expression: BSD-3-Clause
9
+ License-File: LICENSE
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Python: >=3.9
13
+ Description-Content-Type: text/markdown
14
+
15
+ # system-parse-lib
16
+
17
+ A small Python library for reading system information on Linux: OS name, kernel version, uptime, desktop environment, session type, CPU and GPU models and vendors, and basic user details. One module, no third-party dependencies, and no external commands: everything is read from `/etc`, `/proc` and `/sys`.
18
+
19
+ ![License](https://img.shields.io/badge/license-BSD--3--Clause-blue)
20
+ ![Python](https://img.shields.io/badge/python-3-yellow)
21
+ ![Platform](https://img.shields.io/badge/platform-Linux-lightgrey)
22
+
23
+ **Documentation:** https://black-mesa-studios.github.io/system-parse-lib/
24
+
25
+ ## Features
26
+
27
+ - Distro ID and pretty name, read from `/etc/os-release`
28
+ - Current username and hostname
29
+ - Kernel version and uptime (as seconds or readable text)
30
+ - Desktop environment, from `XDG_CURRENT_DESKTOP` or `DESKTOP_SESSION`
31
+ - Session type (Wayland, X11, tty), from `XDG_SESSION_TYPE`
32
+ - CPU model, from `/proc/cpuinfo`
33
+ - GPUs with vendor, model and kernel driver, from `/sys/bus/pci/devices`
34
+
35
+ ## Requirements
36
+
37
+ - Linux
38
+ - Python 3.10 or newer
39
+ - Optional: a `pci.ids` file (from the `hwdata` or `pciids` package) so `get_gpu()` can show real model names
40
+
41
+ ## Installation
42
+
43
+ There's no package yet. Clone the repo and copy `systemparselib.py` next to your script:
44
+
45
+ ```
46
+ git clone https://github.com/black-mesa-studios/system-parse-lib.git
47
+ cp system-parse-lib/systemparselib.py ./
48
+ ```
49
+
50
+ ## Usage
51
+
52
+ ```python
53
+ import systemparselib
54
+
55
+ sysinfo = systemparselib.Main()
56
+
57
+ print(sysinfo.get_pretty_name()) # e.g. Arch Linux
58
+ print(sysinfo.get_de()) # e.g. KDE
59
+ print(sysinfo.get_session_type()) # e.g. wayland
60
+ print(sysinfo.get_kernel_version()) # e.g. 6.11.2-arch1-1
61
+ print(sysinfo.get_pretty_uptime()) # e.g. up 3 hours, 12 minutes
62
+ print(sysinfo.get_cpu()) # e.g. AMD Ryzen 5 5600X 6-Core Processor
63
+ print(sysinfo.get_gpu()) # e.g. [GPU(vendor='AMD', model='...', driver='amdgpu')]
64
+ print(f"{sysinfo.get_username()}@{sysinfo.get_hostname()}")
65
+ ```
66
+
67
+ ## Functions
68
+
69
+ All functions live on the `Main` class.
70
+
71
+ | Function | Returns | Description |
72
+ | --- | --- | --- |
73
+ | `get_distro_id()` | `str \| None` | Short distro ID, like `arch` or `ubuntu` |
74
+ | `get_pretty_name()` | `str \| None` | Human-readable OS name |
75
+ | `get_username()` | `str` | Current user's name |
76
+ | `get_hostname()` | `str` | Machine hostname |
77
+ | `get_de()` | `str \| None` | Desktop environment, or `None` if none is set |
78
+ | `get_session_type()` | `str` | Session type from `XDG_SESSION_TYPE`, like `wayland` or `x11` |
79
+ | `get_kernel_version()` | `str` | Kernel release, like `6.11.2-arch1-1` |
80
+ | `get_uptime_seconds()` | `int \| None` | Seconds since boot |
81
+ | `get_pretty_uptime()` | `str \| None` | Readable uptime, like `up 3 hours, 12 minutes` |
82
+ | `get_cpu()` | `str \| None` | CPU model name |
83
+ | `get_gpu()` | `list[GPU]` | One `GPU(vendor, model, driver)` per display device |
84
+
85
+ Full details are in the [documentation](https://black-mesa-studios.github.io/system-parse-lib/).
86
+
87
+ ## Testing
88
+
89
+ `test.py` prints the output of every function so you can check it on your machine:
90
+
91
+ ```
92
+ python3 test.py
93
+ ```
94
+
95
+ ## License
96
+
97
+ Released under the [BSD 3-Clause License](LICENSE). Copyright 2026 Black Mesa Studios.
@@ -0,0 +1,6 @@
1
+ system-parse-lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ system-parse-lib/systemparselib.py,sha256=kODuVzQGdlyUtvYuxVlvaFG8mZwaQF3e6_EBt9PD4H8,5033
3
+ system_parse_lib-0.0.1.dist-info/METADATA,sha256=S9IJsE3vmx5g5AjtjN0s6_oCZ8LRMheluheSIkV9j3c,3818
4
+ system_parse_lib-0.0.1.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
5
+ system_parse_lib-0.0.1.dist-info/licenses/LICENSE,sha256=OUU7y5SgDmsRqYh0PtRbnl7hdwCO-EHksvXNZiql3uo,1505
6
+ system_parse_lib-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Black Mesa Studios
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.