Name | pyhabitat JSON |
Version |
1.0.15
JSON |
| download |
home_page | None |
Summary | A lightweight library for detecting system environment, GUI, and build properties. |
upload_time | 2025-10-21 01:02:57 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.8 |
license | None |
keywords |
environment
os-detection
gui
build-system
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# pyhabitat 🧭
## An Introspection Library for Python Environments and Builds
**`pyhabitat`** is a **lightweight library for Python build and environment introspection**. It accurately and securely determines the execution context of a running script by providing definitive checks for:
* **OS and Environments:** Operating Systems and common container/emulation environments (e.g., Termux, iSH).
* **Build States:** Application build systems (e.g., PyInstaller, pipx).
* **GUI Backends:** Availability of graphical toolkits (e.g., Matplotlib, Tkinter).
Stop writing verbose `sys.platform` and environment variable checks. Use **`pyhabitat`** to implement clean, **architectural logic** based on the execution habitat.
---
Read the code on [github](https://github.com/City-of-Memphis-Wastewater/pyhabitat/blob/main/pyhabitat/environment.py). 🌐
---
## 📦 Installation
```bash
pip install pyhabitat
```
---
<details>
<summary> 🧠 Motivation </summary>
This library is especially useful for **leveraging Python in mobile environments** (`Termux` on Android and `iSH` on iOS), which often have particular limitations and require special handling. For example, it helps automate work-arounds like using **localhost plotting** when `matplotlib` is unavailable or **web-based interfaces** when `tkinter` is missing.
Our team is fundamentally driven by enabling mobile computing for true utility applications, leveraging environments like Termux (Android) and iSH (iOS). This includes highly practical solutions, such as deploying a lightweight Python web server (e.g., Flask, http.server, FastAPI) directly on a handset, or orchestrating full-stack, utility-grade applications that allow technicians to manage data and systems right from their mobile device in a way that is cross-platform and not overly catered to the App Store.
Another key goal of this project is to facilitate the orchestration of wider system installation for **`pipx` CLI tools** for additional touch points, like context menus and widgets.
Ultimately, [City-of-Memphis-Wastewater](https://github.com/City-of-Memphis-Wastewater) aims to produce **reference-quality code** for the documented proper approach. We recognize that many people (and bots) are searching for ideal solutions, and our functions are built upon extensive research and testing to go **beyond simple `platform.system()` checks**.
</details>
---
<details>
<summary> 🚀 Features </summary>
* **Definitive Environment Checks:** Rigorous checks catered to Termux and iSH (iOS Alpine). Accurate, typical modern detection for Windows, macOS (Apple), Linux, FreeBSD, Android.
* **GUI Availability:** Rigorous, cached checks to determine if the environment supports a graphical popup window (Tkinter/Matplotlib TkAgg) or just headless image export (Matplotlib Agg).
* **Build/Packaging Detection:** Reliable detection of standalone executables built by tools like PyInstaller, and, crucially, correct identification and exclusion of pipx-managed virtual environments, which also user binaries that could conflate the check.
* **Executable Type Inspection:** Uses file magic numbers (ELF and MZ) to confirm if the running script is a monolithic, frozen binary (non-pipx).
</details>
---
<details>
<summary> 📚 Function Reference </summary>
### OS and Environment Checking
Key question: "What is this running on?"
| Function | Description |
| :--- | :--- |
| `is_windows()` | Returns `True` on Windows. |
| `is_apple()` | Returns `True` on macOS (Darwin). |
| `is_linux()` | Returns `True` on Linux in general. |
| `is_termux()` | Returns `True` if running in the Termux Android environment. |
| `is_ish_alpine()` | Returns `True` if running in the iSH Alpine Linux iOS emulator. |
| `is_android()` | Returns `True` on any Android-based Linux environment. |
### Packaging and Build Checking
Key question: "What is the character of my executable?"
| Function | Description |
| :--- | :--- |
| `is_frozen()` | Returns `True` if the script is running as a standalone executable (any bundler). |
| `is_pipx()` | Returns `True` if running from a pipx managed virtual environment. |
| `is_elf()` | Checks if the executable is an ELF binary (Linux standalone executable), excluding pipx. |
| `is_windows_portable_executable()` | Checks if the executable is a Windows PE binary (MZ header), excluding pipx. |
| `is_macos_executable()` | Checks if the executable is a macOS/Darwin Mach-O binary, excluding pipx. |
### Capability Checking
Key Question: "What could I do next?"
| Function | Description |
| :--- | :--- |
| `tkinter_is_available()` | Checks if Tkinter is imported and can successfully create a window. |
| `matplotlib_is_available_for_gui_plotting(termux_has_gui=False)` | Checks for Matplotlib and its TkAgg backend, required for interactive plotting. |
| `matplotlib_is_available_for_headless_image_export()` | Checks for Matplotlib and its Agg backend, required for saving images without a GUI. |
| `interactive_terminal_is_available()` | Checks if standard input and output streams are connected to a TTY (allows safe use of interactive prompts). |
| `web_browser_is_available()` | Check if a web browser can be launched in the current environment (allows safe use of web-based prompts and localhost plotting). |
### Actions
| Function | Description |
| :--- | :--- |
| `open_text_file_for_editing()` | Smoothly opens a text file for editing (for configuration editing prompted by a CLI flag). |
</details>
---
<details>
<summary> 💻 Usage Examples </summary>
The module exposes all detection functions directly for easy access.
### 0\. Current Use
The `pipeline-eds` package uses the `pyhabitat` library to handle [configuration](https://github.com/City-of-Memphis-Wastewater/pipeline/blob/main/src/pipeline/security_and_config.py) and [plotting](https://github.com/City-of-Memphis-Wastewater/pipeline/blob/main/src/pipeline/cli.py), among other things.
### 1\. Checking Environment and Build Type
```python
from pyhabitat import is_termux, is_windows, is_pipx, is_frozen
if is_pipx():
print("Running inside a pipx virtual environment. This is not a standalone binary.")
elif is_frozen():
print("Running as a frozen executable (PyInstaller, cx_Freeze, etc.).")
elif is_termux():
# Expected cases:
#- pkg install python-numpy python-cryptography
#- Avoiding matplotlib unless the user explicitly confirms that termux_has_gui=False in matplotlib_is_available_for_gui_plotting(termux_has_gui=False).
#- Auto-selection of 'termux-open-url' and 'xdg-open' in logic.
#- Installation on the system, like orchestrating the construction of Termux Widget entries in ~/.shortcuts.
print("Running in the Termux environment on Android.")
elif is_windows():
print("Running on Windows.")
```
### 2\. Checking GUI and Plotting Availability
Use these functions to determine if you can show an interactive plot or if you must save an image file.
```python
from pyhabitat import matplotlib_is_available_for_gui_plotting, matplotlib_is_available_for_headless_image_export,
if matplotlib_is_available_for_gui_plotting():
# We can safely call plt.show()
print("GUI plotting is available! Using TkAgg backend.")
import matplotlib.pyplot as plt
plt.figure()
plt.show()
elif matplotlib_is_available_for_headless_image_export():
# We must save the plot to a file or buffer
print("GUI unavailable, but headless image export is possible.")
# Code to use 'Agg' backend and save to disk...
else:
print("Matplotlib is not installed or the environment is too restrictive for plotting.")
```
### 3\. Text Editing
Use this function to smoothly open a text file for editing.
Ideal use case: Edit a configuration file, if prompted by a CLI command like 'config --textedit'.
```python
open_text_file_for_editing(filepath=Path('./config.json'))
```
</details>
---
## 🤝 Contributing
Contributions are welcome\! If you find an environment or build system that is not correctly detected (e.g., a new container or a specific bundler), please open an issue or submit a pull request with the relevant detection logic.
## 📄 License
This project is licensed under the MIT License. See the LICENSE file for details.
Raw data
{
"_id": null,
"home_page": null,
"name": "pyhabitat",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "environment, os-detection, gui, build-system",
"author": null,
"author_email": "George Clayton Bennett <george.bennett@memphistn.gov>",
"download_url": "https://files.pythonhosted.org/packages/d7/e7/1b1814863f294a4d2aeaec1234c1112ff4d2ce17304521a6d06f8f724154/pyhabitat-1.0.15.tar.gz",
"platform": null,
"description": "# pyhabitat \ud83e\udded\n\n## An Introspection Library for Python Environments and Builds\n\n**`pyhabitat`** is a **lightweight library for Python build and environment introspection**. It accurately and securely determines the execution context of a running script by providing definitive checks for:\n\n* **OS and Environments:** Operating Systems and common container/emulation environments (e.g., Termux, iSH).\n* **Build States:** Application build systems (e.g., PyInstaller, pipx).\n* **GUI Backends:** Availability of graphical toolkits (e.g., Matplotlib, Tkinter).\n\nStop writing verbose `sys.platform` and environment variable checks. Use **`pyhabitat`** to implement clean, **architectural logic** based on the execution habitat.\n\n---\n\nRead the code on [github](https://github.com/City-of-Memphis-Wastewater/pyhabitat/blob/main/pyhabitat/environment.py). \ud83c\udf10\n\n---\n\n## \ud83d\udce6 Installation\n\n```bash\npip install pyhabitat\n```\n\n---\n\n<details>\n<summary> \ud83e\udde0 Motivation </summary>\n\nThis library is especially useful for **leveraging Python in mobile environments** (`Termux` on Android and `iSH` on iOS), which often have particular limitations and require special handling. For example, it helps automate work-arounds like using **localhost plotting** when `matplotlib` is unavailable or **web-based interfaces** when `tkinter` is missing. \n\nOur team is fundamentally driven by enabling mobile computing for true utility applications, leveraging environments like Termux (Android) and iSH (iOS). This includes highly practical solutions, such as deploying a lightweight Python web server (e.g., Flask, http.server, FastAPI) directly on a handset, or orchestrating full-stack, utility-grade applications that allow technicians to manage data and systems right from their mobile device in a way that is cross-platform and not overly catered to the App Store.\n\nAnother key goal of this project is to facilitate the orchestration of wider system installation for **`pipx` CLI tools** for additional touch points, like context menus and widgets.\n\nUltimately, [City-of-Memphis-Wastewater](https://github.com/City-of-Memphis-Wastewater) aims to produce **reference-quality code** for the documented proper approach. We recognize that many people (and bots) are searching for ideal solutions, and our functions are built upon extensive research and testing to go **beyond simple `platform.system()` checks**.\n\n</details>\n\n---\n\n<details>\n<summary> \ud83d\ude80 Features </summary>\n\n * **Definitive Environment Checks:** Rigorous checks catered to Termux and iSH (iOS Alpine). Accurate, typical modern detection for Windows, macOS (Apple), Linux, FreeBSD, Android.\n * **GUI Availability:** Rigorous, cached checks to determine if the environment supports a graphical popup window (Tkinter/Matplotlib TkAgg) or just headless image export (Matplotlib Agg).\n * **Build/Packaging Detection:** Reliable detection of standalone executables built by tools like PyInstaller, and, crucially, correct identification and exclusion of pipx-managed virtual environments, which also user binaries that could conflate the check.\n * **Executable Type Inspection:** Uses file magic numbers (ELF and MZ) to confirm if the running script is a monolithic, frozen binary (non-pipx).\n\n</details>\n \n---\n\n<details>\n<summary> \ud83d\udcda Function Reference </summary>\n\n### OS and Environment Checking\n\nKey question: \"What is this running on?\"\n\n| Function | Description |\n| :--- | :--- |\n| `is_windows()` | Returns `True` on Windows. |\n| `is_apple()` | Returns `True` on macOS (Darwin). |\n| `is_linux()` | Returns `True` on Linux in general. |\n| `is_termux()` | Returns `True` if running in the Termux Android environment. |\n| `is_ish_alpine()` | Returns `True` if running in the iSH Alpine Linux iOS emulator. |\n| `is_android()` | Returns `True` on any Android-based Linux environment. |\n\n### Packaging and Build Checking\n\nKey question: \"What is the character of my executable?\"\n\n| Function | Description |\n| :--- | :--- |\n| `is_frozen()` | Returns `True` if the script is running as a standalone executable (any bundler). |\n| `is_pipx()` | Returns `True` if running from a pipx managed virtual environment. |\n| `is_elf()` | Checks if the executable is an ELF binary (Linux standalone executable), excluding pipx. |\n| `is_windows_portable_executable()` | Checks if the executable is a Windows PE binary (MZ header), excluding pipx. |\n| `is_macos_executable()` | Checks if the executable is a macOS/Darwin Mach-O binary, excluding pipx. |\n\n### Capability Checking\n\nKey Question: \"What could I do next?\"\n\n| Function | Description |\n| :--- | :--- |\n| `tkinter_is_available()` | Checks if Tkinter is imported and can successfully create a window. |\n| `matplotlib_is_available_for_gui_plotting(termux_has_gui=False)` | Checks for Matplotlib and its TkAgg backend, required for interactive plotting. |\n| `matplotlib_is_available_for_headless_image_export()` | Checks for Matplotlib and its Agg backend, required for saving images without a GUI. |\n| `interactive_terminal_is_available()` | Checks if standard input and output streams are connected to a TTY (allows safe use of interactive prompts). |\n| `web_browser_is_available()` | Check if a web browser can be launched in the current environment (allows safe use of web-based prompts and localhost plotting). \t|\n\n### Actions\n\n| Function | Description |\n| :--- | :--- |\n| `open_text_file_for_editing()` | Smoothly opens a text file for editing (for configuration editing prompted by a CLI flag). |\n\n</details>\n\n---\n\n<details>\n<summary> \ud83d\udcbb Usage Examples </summary>\n\nThe module exposes all detection functions directly for easy access.\n\n### 0\\. Current Use\n\nThe `pipeline-eds` package uses the `pyhabitat` library to handle [configuration](https://github.com/City-of-Memphis-Wastewater/pipeline/blob/main/src/pipeline/security_and_config.py) and [plotting](https://github.com/City-of-Memphis-Wastewater/pipeline/blob/main/src/pipeline/cli.py), among other things.\n\n### 1\\. Checking Environment and Build Type\n\n```python\nfrom pyhabitat import is_termux, is_windows, is_pipx, is_frozen\n\nif is_pipx():\n print(\"Running inside a pipx virtual environment. This is not a standalone binary.\")\n\nelif is_frozen():\n print(\"Running as a frozen executable (PyInstaller, cx_Freeze, etc.).\")\n\nelif is_termux(): \n\t# Expected cases: \n\t#- pkg install python-numpy python-cryptography\n\t#- Avoiding matplotlib unless the user explicitly confirms that termux_has_gui=False in matplotlib_is_available_for_gui_plotting(termux_has_gui=False).\n\t#- Auto-selection of 'termux-open-url' and 'xdg-open' in logic.\n\t#- Installation on the system, like orchestrating the construction of Termux Widget entries in ~/.shortcuts.\n print(\"Running in the Termux environment on Android.\")\n \nelif is_windows():\n print(\"Running on Windows.\")\n```\n\n### 2\\. Checking GUI and Plotting Availability\n\nUse these functions to determine if you can show an interactive plot or if you must save an image file.\n\n```python\nfrom pyhabitat import matplotlib_is_available_for_gui_plotting, matplotlib_is_available_for_headless_image_export, \n\nif matplotlib_is_available_for_gui_plotting():\n # We can safely call plt.show()\n print(\"GUI plotting is available! Using TkAgg backend.\")\n import matplotlib.pyplot as plt\n plt.figure()\n plt.show()\n\nelif matplotlib_is_available_for_headless_image_export():\n # We must save the plot to a file or buffer\n print(\"GUI unavailable, but headless image export is possible.\")\n # Code to use 'Agg' backend and save to disk...\n \nelse:\n print(\"Matplotlib is not installed or the environment is too restrictive for plotting.\")\n```\n\n### 3\\. Text Editing\n\nUse this function to smoothly open a text file for editing. \nIdeal use case: Edit a configuration file, if prompted by a CLI command like 'config --textedit'.\n\n```python\nopen_text_file_for_editing(filepath=Path('./config.json'))\n```\n</details>\n\n---\n\n## \ud83e\udd1d Contributing\n\nContributions are welcome\\! If you find an environment or build system that is not correctly detected (e.g., a new container or a specific bundler), please open an issue or submit a pull request with the relevant detection logic.\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the MIT License. See the LICENSE file for details.\n",
"bugtrack_url": null,
"license": null,
"summary": "A lightweight library for detecting system environment, GUI, and build properties.",
"version": "1.0.15",
"project_urls": null,
"split_keywords": [
"environment",
" os-detection",
" gui",
" build-system"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "784556364179fd4dbb0903edd895fee8f0e64312ecf7f4ae396f24f74f61e009",
"md5": "edccb0daa14bfc05af9b9011350a00c5",
"sha256": "c364f68d94ddc7f3b60b0ece0ee30f61374efd462d04db97647dfac60d76cfa0"
},
"downloads": -1,
"filename": "pyhabitat-1.0.15-py3-none-any.whl",
"has_sig": false,
"md5_digest": "edccb0daa14bfc05af9b9011350a00c5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 12187,
"upload_time": "2025-10-21T01:02:55",
"upload_time_iso_8601": "2025-10-21T01:02:55.510740Z",
"url": "https://files.pythonhosted.org/packages/78/45/56364179fd4dbb0903edd895fee8f0e64312ecf7f4ae396f24f74f61e009/pyhabitat-1.0.15-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d7e71b1814863f294a4d2aeaec1234c1112ff4d2ce17304521a6d06f8f724154",
"md5": "cf641965fc27ab8707d8efec54547ef6",
"sha256": "55f35730f6c7c0a5cb8a947af5f105c909e35c0e2609410dbfa0975a7e415b6b"
},
"downloads": -1,
"filename": "pyhabitat-1.0.15.tar.gz",
"has_sig": false,
"md5_digest": "cf641965fc27ab8707d8efec54547ef6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 14357,
"upload_time": "2025-10-21T01:02:57",
"upload_time_iso_8601": "2025-10-21T01:02:57.087890Z",
"url": "https://files.pythonhosted.org/packages/d7/e7/1b1814863f294a4d2aeaec1234c1112ff4d2ce17304521a6d06f8f724154/pyhabitat-1.0.15.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-21 01:02:57",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "pyhabitat"
}