python-template-project 0.1.0__py3-none-any.whl → 0.1.15__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.
- __init__.py +0 -0
- main.py +153 -0
- python_template_project/_version.py +21 -0
- {python_template_project-0.1.0.dist-info → python_template_project-0.1.15.dist-info}/METADATA +26 -22
- {python_template_project-0.1.0.dist-info → python_template_project-0.1.15.dist-info}/RECORD +9 -5
- {python_template_project-0.1.0.dist-info → python_template_project-0.1.15.dist-info}/WHEEL +2 -1
- python_template_project-0.1.15.dist-info/top_level.txt +3 -0
- {python_template_project-0.1.0.dist-info → python_template_project-0.1.15.dist-info}/entry_points.txt +0 -0
- {python_template_project-0.1.0.dist-info → python_template_project-0.1.15.dist-info}/licenses/LICENSE +0 -0
__init__.py
ADDED
|
File without changes
|
main.py
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Unified entry point for CLI and GUI application.
|
|
4
|
+
Automatically detects whether to run CLI or GUI based on how the application is started.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def is_console_attached():
|
|
12
|
+
"""
|
|
13
|
+
Check if the application is running in a console environment.
|
|
14
|
+
Returns True if launched from console, False if launched via double-click.
|
|
15
|
+
"""
|
|
16
|
+
try:
|
|
17
|
+
# On Windows, check if we have a console attached
|
|
18
|
+
if os.name == "nt":
|
|
19
|
+
import ctypes
|
|
20
|
+
|
|
21
|
+
kernel32 = ctypes.windll.kernel32
|
|
22
|
+
# GetConsoleWindow returns 0 if no console is attached
|
|
23
|
+
console_window = kernel32.GetConsoleWindow()
|
|
24
|
+
if console_window == 0:
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
# Check if the console was created by this process
|
|
28
|
+
# (indicates double-click launch with console auto-created)
|
|
29
|
+
process_list = kernel32.GetConsoleProcessList(None, 0)
|
|
30
|
+
if process_list <= 1:
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
return True
|
|
34
|
+
else:
|
|
35
|
+
# On Unix-like systems (macOS, Linux), check multiple indicators
|
|
36
|
+
# Check if stdout is a terminal
|
|
37
|
+
if not sys.stdout.isatty():
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
# Additional check for macOS: Check if we're running in a .app bundle
|
|
41
|
+
if sys.platform == "darwin":
|
|
42
|
+
# If we're in a .app bundle, we're likely launched via double-click
|
|
43
|
+
executable_path = sys.executable
|
|
44
|
+
if ".app/" in executable_path:
|
|
45
|
+
# We're in an app bundle, check if we have a real terminal
|
|
46
|
+
# by checking if TERM environment variable is set
|
|
47
|
+
return os.environ.get("TERM") is not None
|
|
48
|
+
|
|
49
|
+
return True
|
|
50
|
+
except Exception as ex:
|
|
51
|
+
# Fallback: assume GUI if we can't determine
|
|
52
|
+
print(ex)
|
|
53
|
+
return False
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def has_command_line_args():
|
|
57
|
+
"""Check if command line arguments (beyond script name) are provided."""
|
|
58
|
+
return len(sys.argv) > 1
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def main():
|
|
62
|
+
"""Main entry point that decides between CLI and GUI."""
|
|
63
|
+
|
|
64
|
+
# Force CLI mode if command line arguments are provided
|
|
65
|
+
if has_command_line_args():
|
|
66
|
+
run_cli()
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
# Check if we're in a console environment
|
|
70
|
+
if is_console_attached():
|
|
71
|
+
# We're in a console - offer choice or default to CLI
|
|
72
|
+
print("Python Template Project")
|
|
73
|
+
print("=" * 50)
|
|
74
|
+
print("Detected console environment.")
|
|
75
|
+
print("Options:")
|
|
76
|
+
print(" 1. Run CLI interface (default)")
|
|
77
|
+
print(" 2. Run GUI interface")
|
|
78
|
+
print(" 3. Show help")
|
|
79
|
+
print()
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
choice = input("Select option [1]: ").strip()
|
|
83
|
+
if choice == "2":
|
|
84
|
+
run_gui()
|
|
85
|
+
elif choice == "3":
|
|
86
|
+
show_help()
|
|
87
|
+
else:
|
|
88
|
+
run_cli()
|
|
89
|
+
except (KeyboardInterrupt, EOFError):
|
|
90
|
+
print("\nExiting...")
|
|
91
|
+
sys.exit(0)
|
|
92
|
+
else:
|
|
93
|
+
# Launched via double-click - start GUI
|
|
94
|
+
run_gui()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def run_cli():
|
|
98
|
+
"""Launch the CLI interface."""
|
|
99
|
+
try:
|
|
100
|
+
from python_template_project.cli.cli import main as cli_main
|
|
101
|
+
|
|
102
|
+
cli_main()
|
|
103
|
+
except ImportError as e:
|
|
104
|
+
print(f"Error importing CLI module: {e}")
|
|
105
|
+
sys.exit(1)
|
|
106
|
+
except Exception as e:
|
|
107
|
+
print(f"Error running CLI: {e}")
|
|
108
|
+
sys.exit(1)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def run_gui():
|
|
112
|
+
"""Launch the GUI interface."""
|
|
113
|
+
try:
|
|
114
|
+
from python_template_project.gui.gui import main as gui_main
|
|
115
|
+
|
|
116
|
+
gui_main()
|
|
117
|
+
except ImportError as e:
|
|
118
|
+
print(f"Error importing GUI module: {e}")
|
|
119
|
+
# If GUI fails, fallback to CLI
|
|
120
|
+
print("Falling back to CLI interface...")
|
|
121
|
+
run_cli()
|
|
122
|
+
except Exception as e:
|
|
123
|
+
print(f"Error running GUI: {e}")
|
|
124
|
+
print("Falling back to CLI interface...")
|
|
125
|
+
run_cli()
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def show_help():
|
|
129
|
+
"""Show help information."""
|
|
130
|
+
print("""
|
|
131
|
+
Unified Application
|
|
132
|
+
|
|
133
|
+
Usage:
|
|
134
|
+
When launched from console:
|
|
135
|
+
- Without arguments: Interactive mode selection
|
|
136
|
+
- With arguments: Direct CLI mode
|
|
137
|
+
|
|
138
|
+
When launched via double-click:
|
|
139
|
+
- Automatically starts GUI interface
|
|
140
|
+
|
|
141
|
+
Command Line Arguments:
|
|
142
|
+
Run with any CLI arguments to force CLI mode.
|
|
143
|
+
|
|
144
|
+
Examples:
|
|
145
|
+
python main.py --help # Shows CLI help
|
|
146
|
+
python main.py # Interactive mode selection
|
|
147
|
+
double-click main.exe # Starts GUI
|
|
148
|
+
|
|
149
|
+
""")
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
if __name__ == "__main__":
|
|
153
|
+
main()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
+
|
|
6
|
+
TYPE_CHECKING = False
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from typing import Tuple
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
11
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
12
|
+
else:
|
|
13
|
+
VERSION_TUPLE = object
|
|
14
|
+
|
|
15
|
+
version: str
|
|
16
|
+
__version__: str
|
|
17
|
+
__version_tuple__: VERSION_TUPLE
|
|
18
|
+
version_tuple: VERSION_TUPLE
|
|
19
|
+
|
|
20
|
+
__version__ = version = '0.1.15'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 1, 15)
|
{python_template_project-0.1.0.dist-info → python_template_project-0.1.15.dist-info}/METADATA
RENAMED
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-template-project
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.15
|
|
4
4
|
Summary: Feature-rich Python project template designed for robustness and ease of use.
|
|
5
5
|
Author: pamagister
|
|
6
|
-
License-File: LICENSE
|
|
7
6
|
Requires-Python: <3.12,>=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
8
9
|
Requires-Dist: gpxpy>=1.6.2
|
|
9
10
|
Requires-Dist: pydantic>=2.11.7
|
|
10
11
|
Requires-Dist: pyyaml>=6.0.2
|
|
11
12
|
Requires-Dist: srtm-py>=0.3.7
|
|
12
13
|
Provides-Extra: dev
|
|
13
|
-
Requires-Dist:
|
|
14
|
-
Requires-Dist:
|
|
15
|
-
Requires-Dist:
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist: ruff>=0.11.13; extra ==
|
|
14
|
+
Requires-Dist: pytest>=8.4.0; extra == "dev"
|
|
15
|
+
Requires-Dist: pytest-mock>=3.14.1; extra == "dev"
|
|
16
|
+
Requires-Dist: coverage>=7.8.2; extra == "dev"
|
|
17
|
+
Requires-Dist: flake8>=7.2.0; extra == "dev"
|
|
18
|
+
Requires-Dist: black>=25.1.0; extra == "dev"
|
|
19
|
+
Requires-Dist: isort>=6.0.1; extra == "dev"
|
|
20
|
+
Requires-Dist: pytest-cov>=6.1.1; extra == "dev"
|
|
21
|
+
Requires-Dist: mypy>=1.16.0; extra == "dev"
|
|
22
|
+
Requires-Dist: gitchangelog>=3.0.4; extra == "dev"
|
|
23
|
+
Requires-Dist: pyinstaller>=5.8; extra == "dev"
|
|
24
|
+
Requires-Dist: pre-commit>=4.2.0; extra == "dev"
|
|
25
|
+
Requires-Dist: ruff>=0.11.13; extra == "dev"
|
|
25
26
|
Provides-Extra: docs
|
|
26
|
-
Requires-Dist: mkdocs
|
|
27
|
-
Requires-Dist: mkdocs>=
|
|
28
|
-
Requires-Dist: pygments>=2.19.1; extra ==
|
|
29
|
-
|
|
27
|
+
Requires-Dist: mkdocs>=1.6.1; extra == "docs"
|
|
28
|
+
Requires-Dist: mkdocs-awesome-nav>=2.6.1; extra == "docs"
|
|
29
|
+
Requires-Dist: pygments>=2.19.1; extra == "docs"
|
|
30
|
+
Dynamic: license-file
|
|
30
31
|
|
|
31
32
|
# Welcome to python-template-project
|
|
32
33
|
|
|
@@ -46,17 +47,20 @@ This template provides a solid foundation for your next Python project, incorpor
|
|
|
46
47
|
## Feature overview
|
|
47
48
|
|
|
48
49
|
* **Testing:** Unit testing setup with `pytest`.
|
|
49
|
-
* **CI/CD:**
|
|
50
|
-
* **Code Formatting:** Pre-commit hook with the
|
|
50
|
+
* **CI/CD:** [GitHub Actions](https://github.com/features/actions) for automated builds (Windows, macOS), unit tests, and code checks.
|
|
51
|
+
* **Code Formatting and Linting:** Pre-commit hook with the [RUFF auto-formatter](https://docs.astral.sh/ruff/) to ensure consistent code style.
|
|
51
52
|
* **Automated Builds:** GitHub pipeline for automatically building a Windows executable and a macOS installer.
|
|
52
|
-
* **Package Management:** Utilizes
|
|
53
|
+
* **Package Management:** Utilizes [uv](https://docs.astral.sh/uv/getting-started/), an extremely fast Python package manager, with dependencies managed in `pyproject.toml`.
|
|
53
54
|
* **Parameter-Driven Automation:**
|
|
54
55
|
* Automatic generation of a configuration file from parameter definitions.
|
|
55
56
|
* Automatic generation of a Command-Line Interface (CLI) from the same parameters.
|
|
56
57
|
* Automatic generation of CLI API documentation.
|
|
57
|
-
* **Documentation:** Configuration for publishing documentation on Read the Docs.
|
|
58
|
+
* **Documentation:** Configuration for publishing documentation on [Read the Docs](https://about.readthedocs.com/) using [mkdocs](https://www.mkdocs.org/) .
|
|
58
59
|
* **Workflow Automation:** A `Makefile` is included to simplify and automate common development tasks.
|
|
59
60
|
* **Minimalist GUI:** Comes with a basic GUI based on [tkinker](https://tkdocs.com/tutorial/index.html) that includes an auto-generated settings menu based on your defined parameters.
|
|
61
|
+
* **Release pipeline:** Automated releases unsing the Makefile `make release` command, which creates a new tag and pushes it to the remote repo. The `release` pipeline will automatically create a new release on GitHub and trigger a release on PyPI.
|
|
62
|
+
* **[setuptools](https://pypi.org/project/setuptools/)** is used to package the project and manage dependencies.
|
|
63
|
+
* **[setuptools-scm](https://pypi.org/project/setuptools-scm/)** is used to automatically generate the `_version.py` file from the `pyproject.toml` file.
|
|
60
64
|
|
|
61
65
|
## Getting started
|
|
62
66
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
main.py,sha256=d6ZpnMxcPBf860gQmuYwPVJg1di6r2CR6gSvFLkAZkk,4448
|
|
1
3
|
python_template_project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
4
|
python_template_project/__main__.py,sha256=JS28LiHoU9Xo4c_RvyLBTDKHqdZRRytJLj6qyrg26mQ,195
|
|
5
|
+
python_template_project/_version.py,sha256=OX-WIjJlMaFvqRmCfLtOYEOYoiov9NdOA089N36rG-g,513
|
|
3
6
|
python_template_project/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
7
|
python_template_project/cli/__main__.py,sha256=qnGkoNNbhnvLTA24X8YTEDxRqDbNEAzgjp9Ki_JYIhs,184
|
|
5
8
|
python_template_project/cli/cli.py,sha256=RvoYKJDjP-PYlX4m5xFnUsuHVJw_3-AgpQwOxhPAH5g,6974
|
|
@@ -11,8 +14,9 @@ python_template_project/core/logging.py,sha256=D99ZAXY9KZvmV7oVlAy3S3fuDf9G7vHvI
|
|
|
11
14
|
python_template_project/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
15
|
python_template_project/gui/__main__.py,sha256=5AaiBxNCAKWcuSQFcQ_lsEQfEsXm6BA5-i5MScdf30c,184
|
|
13
16
|
python_template_project/gui/gui.py,sha256=qJ9SawFywwT7ffPndTzhuLEu2KkzjBspmSccAXgUC2k,21725
|
|
14
|
-
python_template_project-0.1.
|
|
15
|
-
python_template_project-0.1.
|
|
16
|
-
python_template_project-0.1.
|
|
17
|
-
python_template_project-0.1.
|
|
18
|
-
python_template_project-0.1.
|
|
17
|
+
python_template_project-0.1.15.dist-info/licenses/LICENSE,sha256=awOCsWJ58m_2kBQwBUGWejVqZm6wuRtCL2hi9rfa0X4,1211
|
|
18
|
+
python_template_project-0.1.15.dist-info/METADATA,sha256=N0SI3VOLkBfla0VrMu1Xj6H0EQJNJhxYwkKSSZdMmOY,5555
|
|
19
|
+
python_template_project-0.1.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
20
|
+
python_template_project-0.1.15.dist-info/entry_points.txt,sha256=LmgMiqxIVRdD7gkktVBBR0CR4AhkugqlgifuglkPhtI,148
|
|
21
|
+
python_template_project-0.1.15.dist-info/top_level.txt,sha256=9TFlucRiaKsVFCd9mTKCxamJW6LmFnXFXeI7WIvv4AA,38
|
|
22
|
+
python_template_project-0.1.15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|