pyhabitat


Namepyhabitat JSON
Version 1.0.15 PyPI version JSON
download
home_pageNone
SummaryA lightweight library for detecting system environment, GUI, and build properties.
upload_time2025-10-21 01:02:57
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseNone
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"
}
        
Elapsed time: 0.97718s