pyhabitat 1.0.8__py3-none-any.whl → 1.0.10__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.
Potentially problematic release.
This version of pyhabitat might be problematic. Click here for more details.
- pyhabitat/environment.py +5 -3
- {pyhabitat-1.0.8.dist-info → pyhabitat-1.0.10.dist-info}/METADATA +48 -18
- pyhabitat-1.0.10.dist-info/RECORD +7 -0
- pyhabitat-1.0.8.dist-info/RECORD +0 -7
- {pyhabitat-1.0.8.dist-info → pyhabitat-1.0.10.dist-info}/WHEEL +0 -0
- {pyhabitat-1.0.8.dist-info → pyhabitat-1.0.10.dist-info}/licenses/LICENSE +0 -0
- {pyhabitat-1.0.8.dist-info → pyhabitat-1.0.10.dist-info}/top_level.txt +0 -0
pyhabitat/environment.py
CHANGED
|
@@ -418,12 +418,14 @@ def is_pipx(debug=False) -> bool:
|
|
|
418
418
|
|
|
419
419
|
|
|
420
420
|
# --- TTY CHECK ---
|
|
421
|
-
def
|
|
421
|
+
def interactive_terminal_is_available():
|
|
422
422
|
"""
|
|
423
423
|
Check if the script is running in an interactive terminal.
|
|
424
424
|
Assumpton:
|
|
425
|
-
If
|
|
426
|
-
then typer.prompt() will work reliably
|
|
425
|
+
If interactive_terminal_is_available() returns True,
|
|
426
|
+
then typer.prompt() or input() will work reliably,
|
|
427
|
+
without getting lost in a log or lost entirely.
|
|
428
|
+
|
|
427
429
|
"""
|
|
428
430
|
# Check if a tty is attached to stdin
|
|
429
431
|
return sys.stdin.isatty() and sys.stdout.isatty()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyhabitat
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.10
|
|
4
4
|
Summary: A lightweight library for detecting system environment, GUI, and build properties.
|
|
5
5
|
Author-email: George Clayton Bennett <george.bennett@memphistn.gov>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -25,37 +25,53 @@ Dynamic: license-file
|
|
|
25
25
|
|
|
26
26
|
Stop writing verbose `sys.platform` and environment variable checks. Use **`pyhabitat`** to implement clean, **architectural logic** based on the execution habitat.
|
|
27
27
|
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
Read the code on [github](https://github.com/City-of-Memphis-Wastewater/pyhabitat/blob/main/pyhabitat/environment.py). 🌐
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 📦 Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install pyhabitat
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
<details>
|
|
43
|
+
<summary> 🧠 Motivation </summary>
|
|
44
|
+
|
|
28
45
|
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.
|
|
29
46
|
|
|
30
47
|
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.
|
|
31
48
|
|
|
32
|
-
Another key goal of this project is to facilitate the orchestration of wider system installation for **`pipx` CLI tools** for additional touch points, like
|
|
49
|
+
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.
|
|
33
50
|
|
|
34
51
|
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**.
|
|
35
52
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Read the code on [github](https://github.com/City-of-Memphis-Wastewater/pyhabitat/blob/main/pyhabitat/environment.py).
|
|
53
|
+
</details>
|
|
39
54
|
|
|
40
55
|
---
|
|
41
56
|
|
|
42
|
-
|
|
57
|
+
<details>
|
|
58
|
+
<summary> 🚀 Features </summary>
|
|
43
59
|
|
|
44
60
|
* **Definitive Environment Checks:** Rigorous checks catered to Termux and iSH (iOS Alpine). Accurate, typical modern detection for Windows, macOS (Apple), Linux, FreeBSD, Android.
|
|
45
61
|
* **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).
|
|
46
62
|
* **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.
|
|
47
63
|
* **Executable Type Inspection:** Uses file magic numbers (ELF and MZ) to confirm if the running script is a monolithic, frozen binary (non-pipx).
|
|
48
64
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
pip install pyhabitat
|
|
53
|
-
```
|
|
65
|
+
</details>
|
|
66
|
+
|
|
54
67
|
---
|
|
55
68
|
|
|
56
|
-
|
|
69
|
+
<details>
|
|
70
|
+
<summary> 📚 Function Reference </summary>
|
|
71
|
+
|
|
72
|
+
### OS and Environment Checking
|
|
57
73
|
|
|
58
|
-
|
|
74
|
+
Key question: "What is this running on?"
|
|
59
75
|
|
|
60
76
|
| Function | Description |
|
|
61
77
|
| :--- | :--- |
|
|
@@ -66,7 +82,9 @@ pip install pyhabitat
|
|
|
66
82
|
| `is_ish_alpine()` | Returns `True` if running in the iSH Alpine Linux iOS emulator. |
|
|
67
83
|
| `is_android()` | Returns `True` on any Android-based Linux environment. |
|
|
68
84
|
|
|
69
|
-
###
|
|
85
|
+
### Packaging and Build Checking
|
|
86
|
+
|
|
87
|
+
Key question: "What is the character of my executable?"
|
|
70
88
|
|
|
71
89
|
| Function | Description |
|
|
72
90
|
| :--- | :--- |
|
|
@@ -76,27 +94,37 @@ pip install pyhabitat
|
|
|
76
94
|
| `is_windows_portable_executable()` | Checks if the executable is a Windows PE binary (MZ header), excluding pipx. |
|
|
77
95
|
| `is_macos_executable()` | Checks if the executable is a macOS/Darwin Mach-O binary, excluding pipx. |
|
|
78
96
|
|
|
79
|
-
###
|
|
97
|
+
### Capability Checking
|
|
98
|
+
|
|
99
|
+
Key Question: "What could I do next?"
|
|
80
100
|
|
|
81
101
|
| Function | Description |
|
|
82
102
|
| :--- | :--- |
|
|
83
103
|
| `tkinter_is_available()` | Checks if Tkinter is imported and can successfully create a window. |
|
|
84
104
|
| `matplotlib_is_available_for_gui_plotting(termux_has_gui=False)` | Checks for Matplotlib and its TkAgg backend, required for interactive plotting. |
|
|
85
105
|
| `matplotlib_is_available_for_headless_image_export()` | Checks for Matplotlib and its Agg backend, required for saving images without a GUI. |
|
|
86
|
-
| `
|
|
106
|
+
| `interactive_terminal_is_available()` | Checks if standard input and output streams are connected to a TTY (allows safe use of interactive prompts). |
|
|
87
107
|
| `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). |
|
|
88
108
|
|
|
89
109
|
### Actions
|
|
110
|
+
|
|
90
111
|
| Function | Description |
|
|
91
112
|
| :--- | :--- |
|
|
92
113
|
| `open_text_file_in_default_app()` | Smoothly opens a text file for editing (for configuration editing prompted by a CLI flag). |
|
|
93
114
|
|
|
115
|
+
</details>
|
|
116
|
+
|
|
94
117
|
---
|
|
95
118
|
|
|
96
|
-
|
|
119
|
+
<details>
|
|
120
|
+
<summary> 💻 Usage Examples </summary>
|
|
97
121
|
|
|
98
122
|
The module exposes all detection functions directly for easy access.
|
|
99
123
|
|
|
124
|
+
### 0\. Current Use
|
|
125
|
+
|
|
126
|
+
The `pipeline-eds` pacakge 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.
|
|
127
|
+
|
|
100
128
|
### 1\. Checking Environment and Build Type
|
|
101
129
|
|
|
102
130
|
```python
|
|
@@ -125,7 +153,7 @@ elif is_windows():
|
|
|
125
153
|
Use these functions to determine if you can show an interactive plot or if you must save an image file.
|
|
126
154
|
|
|
127
155
|
```python
|
|
128
|
-
from pyhabitat import matplotlib_is_available_for_gui_plotting, matplotlib_is_available_for_headless_image_export
|
|
156
|
+
from pyhabitat import matplotlib_is_available_for_gui_plotting, matplotlib_is_available_for_headless_image_export,
|
|
129
157
|
|
|
130
158
|
if matplotlib_is_available_for_gui_plotting():
|
|
131
159
|
# We can safely call plt.show()
|
|
@@ -151,6 +179,8 @@ Ideal use case: Edit a configuration file, if prompted by a CLI command like 'co
|
|
|
151
179
|
```python
|
|
152
180
|
open_text_file_in_default_app(filepath=Path('./config.json'))
|
|
153
181
|
```
|
|
182
|
+
</details>
|
|
183
|
+
|
|
154
184
|
---
|
|
155
185
|
|
|
156
186
|
## 🤝 Contributing
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
pyhabitat/__init__.py,sha256=fy1SRFXok05bCprjGMCXS5afw27iKBJCLeSQTuBjlRI,1101
|
|
2
|
+
pyhabitat/environment.py,sha256=rteFLXko5VaxwgfQYRR7SBQaRygKqrNr0YjRYQ5mybo,18206
|
|
3
|
+
pyhabitat-1.0.10.dist-info/licenses/LICENSE,sha256=D4fg30ctUGnCJlWu3ONv5-V8JE1v3ctakoJTcVjsJlg,1072
|
|
4
|
+
pyhabitat-1.0.10.dist-info/METADATA,sha256=NgnZUKS9GsVT9e_sKbhzekLes5jrPTSMnvY5LhNfrnc,8819
|
|
5
|
+
pyhabitat-1.0.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
+
pyhabitat-1.0.10.dist-info/top_level.txt,sha256=zXYK44Qu8EqxUETREvd2diMUaB5JiGRErkwFaoLQnnI,10
|
|
7
|
+
pyhabitat-1.0.10.dist-info/RECORD,,
|
pyhabitat-1.0.8.dist-info/RECORD
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
pyhabitat/__init__.py,sha256=fy1SRFXok05bCprjGMCXS5afw27iKBJCLeSQTuBjlRI,1101
|
|
2
|
-
pyhabitat/environment.py,sha256=eGF6BSTNEnbit6RNVhG6JPqckhhnGlYE3vukq_GRPSk,18114
|
|
3
|
-
pyhabitat-1.0.8.dist-info/licenses/LICENSE,sha256=D4fg30ctUGnCJlWu3ONv5-V8JE1v3ctakoJTcVjsJlg,1072
|
|
4
|
-
pyhabitat-1.0.8.dist-info/METADATA,sha256=JMok0YO4zDc0rRa7yEgqrkjfT6m33wmqGwmTJweJsvg,8128
|
|
5
|
-
pyhabitat-1.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
-
pyhabitat-1.0.8.dist-info/top_level.txt,sha256=zXYK44Qu8EqxUETREvd2diMUaB5JiGRErkwFaoLQnnI,10
|
|
7
|
-
pyhabitat-1.0.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|